This is a very naive Rust tanslation of the basic math behind the ed25519 crypto scheme.

In general, it's a straight translation of the Google code, which in
turn is "mostly taken from the ref10 version of Ed25519 in SUPERCOP
10241124.", except that it's been hand translated to rust with some
test case generators. Future versions should clean this up to be more
normally rust-y.
This commit is contained in:
2019-05-14 21:54:59 -07:00
parent 6c61e1c56c
commit d459850c54
46 changed files with 87304 additions and 2 deletions

1453
src/ed25519/constants.rs Normal file

File diff suppressed because it is too large Load Diff

1125
src/ed25519/fe.rs Normal file

File diff suppressed because it is too large Load Diff

289
src/ed25519/mod.rs Normal file
View File

@@ -0,0 +1,289 @@
mod constants;
mod fe;
mod point;
use digest::Digest;
use rand::Rng;
use sha2::Sha512;
use self::fe::*;
use self::point::*;
pub struct ED25519KeyPair {
private: [u8; 32],
prefix: [u8; 32],
public: [u8; 32]
}
impl ED25519KeyPair {
fn blank() -> ED25519KeyPair
{
ED25519KeyPair {
private: [0; 32],
prefix: [0; 32],
public: [0; 32]
}
}
pub fn generate<G: Rng>(rng: &mut G) -> ED25519KeyPair
{
let mut result = ED25519KeyPair::blank();
let mut seed: [u8; 32] = [0; 32];
rng.fill(&mut seed);
let mut hashed = Sha512::digest(&seed);
let (private, prefix) = hashed.split_at_mut(32);
assert_eq!(private.len(), 32);
assert_eq!(prefix.len(), 32);
result.prefix.copy_from_slice(&prefix);
curve25519_scalar_mask(private);
result.private.copy_from_slice(&private);
x25519_public_from_private(&mut result.public, &private);
result
}
pub fn sign(&self, msg: &[u8]) -> Vec<u8>
{
let mut signature_r = [0u8; 32];
let mut signature_s = [0u8; 32];
let mut ctx = Sha512::new();
ctx.input(&self.prefix);
ctx.input(&msg);
let nonce = digest_scalar(ctx.result().as_slice());
let mut r = Point::new();
x25519_ge_scalarmult_base(&mut r, &nonce);
into_encoded_point(&mut signature_r, &r.x, &r.y, &r.z);
let hram_digest = eddsa_digest(&signature_r, &self.public, &msg);
let hram = digest_scalar(&hram_digest);
x25519_sc_muladd(&mut signature_s, &hram, &self.private, &nonce);
let mut result = Vec::with_capacity(64);
result.extend_from_slice(&signature_r);
result.extend_from_slice(&signature_s);
result
}
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool
{
assert_eq!(sig.len(), 64);
let signature_r = &sig[..32];
let signature_s = &sig[32..];
if signature_s[31] & 0b11100000 != 0 {
return false;
}
let mut a = from_encoded_point(&self.public);
invert_vartime(&mut a);
let h_digest = eddsa_digest(signature_r, &self.public, msg);
let h = digest_scalar(&h_digest);
let mut r = Point2::new();
ge_double_scalarmult_vartime(&mut r, &h, &a, &signature_s);
let mut r_check = [0; 32];
into_encoded_point(&mut r_check, &r.x, &r.y, &r.z);
signature_r == r_check
}
}
fn eddsa_digest(signature_r: &[u8], public_key: &[u8], msg: &[u8]) -> Vec<u8>
{
let mut ctx = Sha512::new();
ctx.input(signature_r);
ctx.input(public_key);
ctx.input(msg);
ctx.result().as_slice().to_vec()
}
fn digest_scalar(digest: &[u8]) -> Vec<u8> {
assert_eq!(digest.len(), 512/8);
let mut copy = [0; 512/8];
copy.copy_from_slice(digest);
x25519_sc_reduce(&mut copy);
copy[..32].to_vec()
}
fn into_encoded_point(bytes: &mut [u8], x: &Element, y: &Element, z: &Element)
{
let mut x_over_z = [0; NUM_ELEMENT_LIMBS];
let mut y_over_z = [0; NUM_ELEMENT_LIMBS];
assert_eq!(bytes.len(), 32);
let recip = fe_invert(z);
fe_mul(&mut x_over_z, x, &recip);
fe_mul(&mut y_over_z, y, &recip);
fe_tobytes(bytes, &y_over_z);
let sign_bit = if fe_isnegative(&x_over_z) { 1 } else { 0 };
// The preceding computations must execute in constant time, but this
// doesn't need to.
bytes[31] ^= sign_bit << 7;
}
fn from_encoded_point(encoded: &[u8]) -> Point
{
let mut point = Point::new();
x25519_ge_frombytes_vartime(&mut point, encoded);
point
}
fn invert_vartime(v: &mut Point)
{
for i in 0..NUM_ELEMENT_LIMBS {
v.x[i] = -v.x[i];
v.t[i] = -v.t[i];
}
}
// use cryptonum::signed::{I256};
// use cryptonum::unsigned::{BarrettU256,CryptoNum,Decoder,ModExp,U256,U512};
// use digest::Digest;
// use rand::Rng;
// use rand::distributions::Standard;
// use sha2::Sha512;
// use super::KeyPair;
//
// struct Field {
// x: U256,
// p: U256,
// pu: BarrettU256
// }
//
// impl Field {
// fn unsafe_new(&self, v: U256) -> Field
// {
// Field{ x: v, p: self.p.clone(), pu: self.pu.clone() }
// }
//
// fn new(&self, v: U256) -> Field
// {
// let v2 = self.pu.reduce(&U512::from(v));
// Field{ x: v2, p: self.p.clone(), pu: self.pu.clone() }
// }
//
// fn init(x: U256, p: U256) -> Field
// {
// let pu = BarrettU256::new(p.clone());
// Field{ x, p, pu }
// }
//
// fn add(&self, y: &Field) -> Field
// {
// assert_eq!(self.p, y.p);
// assert_eq!(self.pu, y.pu);
// let v = U512::from(&self.x + &y.x);
// Field { x: self.pu.reduce(&v), p: self.p.clone(), pu: self.pu.clone() }
// }
//
// fn sub(&self, y: &Field) -> Field
// {
// assert_eq!(self.p, y.p);
// assert_eq!(self.pu, y.pu);
// let mut ix = I256::from(&self.x);
// let iy = I256::from(&y.x);
// ix -= iy;
// if ix.is_negative() {
// let mut rx = I256::from(&self.p);
// rx += ix;
// self.new(U256::from(rx))
// } else {
// self.new(U256::from(ix))
// }
// }
//
// fn neg(&self) -> Field
// {
// let mut rx = self.p.clone();
// rx -= &self.x;
// self.new(rx)
// }
//
// fn mul(&self, y: &Field) -> Field
// {
// let v = &self.x * &y.x;
// self.unsafe_new(self.pu.reduce(&v))
// }
//
// fn inv(&self) -> Field
// {
// let mut pm2 = self.p.clone();
// pm2 -= U256::from(2u8);
// let res = self.x.modexp(&pm2, &self.pu);
// self.unsafe_new(res)
// }
//
// fn div(&self, y: &Field) -> Field
// {
// self.mul(&y.inv())
// }
//
// fn sqrt(&self) -> Field
// {
// panic!("field sqrt")
// }
//
// fn is_zero(&self) -> bool
// {
// self.x.is_zero()
// }
//
// fn eq(&self, y: &Field) -> bool
// {
// self.x == y.x
// }
//
// fn neq(&self, y: &Field) -> bool
// {
// self.x != y.x
// }
//
// fn sign(&self) -> Field
// {
// let mut vx = I256::from(&self.x);
// vx %= I256::from(2u64);
// self.unsafe_new(U256::from(vx))
// }
// }
//
// pub struct ED25519Public {
// }
//
// pub struct ED25519Private {
// key: U256
// }
//
// pub struct ED25519Pair {
// public: ED25519Public,
// private: ED25519Private
// }
//
// impl KeyPair for ED25519Pair {
// type Public = ED25519Public;
// type Private = ED25519Private;
//
// fn new(pu: ED25519Public, pr: ED25519Private) -> ED25519Pair
// {
// ED25519Pair{ public: pu, private: pr }
// }
// }
//
// impl ED25519Pair {
// pub fn generate<G: Rng>(g: &mut G) -> ED25519Pair
// {
// let bytes: Vec<u8> = g.sample_iter(&Standard).take(256 / 8).collect();
// let key = U256::from_bytes(&bytes);
// let private = ED25519Private{ key };
// let mut hash = Sha512::digest(&bytes);
// assert_eq!(hash.len(), 64);
// let (scalar, prefix) = hash.split_at_mut(32);
// assert_eq!(scalar.len(), 32);
// assert_eq!(prefix.len(), 32);
// //
// scalar[0] &= 0b11111000u8;
// scalar[31] &= 0b01111111u8;
// scalar[31] |= 0b01000000u8;
// //
//
// let public = ED25519Public{};
// ED25519Pair{ public, private }
// }
// }

1811
src/ed25519/point.rs Normal file

File diff suppressed because it is too large Load Diff

3363
src/ed25519/rfc8032.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,8 @@ pub mod dsa;
/// The `ecdsa` module provides bare-bones support for ECDSA signing,
/// verification, and key generation.
pub mod ecdsa;
/// The `ed25519` provides signing and verification using ED25519.
pub mod ed25519;
/// The `ssh` module provides support for parsing OpenSSH-formatted SSH keys,
/// both public and private.
pub mod ssh;

701
test-generator/ED25519.hs Normal file
View File

@@ -0,0 +1,701 @@
{-# LANGUAGE PackageImports #-}
module ED25519(ed25519Tasks)
where
import Control.Monad(unless)
import "crypto-api" Crypto.Random(SystemRandom)
import "cryptonite" Crypto.Random(getRandomBytes,withDRG)
import Data.ByteString(ByteString,pack,useAsCString)
import qualified Data.ByteString as BS
import Data.Int(Int32)
import qualified Data.Map.Strict as Map
import Data.Word(Word8,Word32,Word64)
import ED25519.PrecompPoints
import Foreign.C.Types(CChar)
import Foreign.Marshal.Alloc(alloca)
import Foreign.Marshal.Array(allocaArray,peekArray,pokeArray)
import Foreign.Ptr(Ptr,castPtr)
import Foreign.Storable(Storable(..))
import Math(showX,showBin)
import Task(Task(..))
cTEST_COUNT :: Int
cTEST_COUNT = 1000
ed25519Tasks :: [Task]
ed25519Tasks = [ loadTests, byteTests, addsubTests, mulTests,
squaringTests, inversionTests, negateTests,
cmovTests, isTests, square2Tests,
pow22523Tests, fbvTests, conversionTests,
ptDoubleTests, maddsubTests, ptAddSubTests,
scalarMultBaseTests, slideTests, scalarMultTests,
reduceTests, muladdTests, pubPrivTests ]
loadTests :: Task
loadTests = Task {
taskName = "ed25519 byte loading",
taskFile = "../testdata/ed25519/load.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
do let (bytes, drg1) = withDRG drg0 (getRandomBytes 4)
res3 <- useAsCString bytes (\ptr -> load_3 ptr)
res4 <- useAsCString bytes (\ptr -> load_4 ptr)
let res = Map.fromList [("x", showBin bytes), ("a", showX res3), ("b", showX res4)]
return (res, fromIntegral res4, (memory0, drg1))
byteTests :: Task
byteTests = Task {
taskName = "ed25519 byte / element conversion",
taskFile = "../testdata/ed25519/bytes.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPackedBytes drg0 $ \ ptra drg1 ->
alloca $ \ ptrc ->
allocaArray 32 $ \ rptr ->
do clearSpace ptrc
pokeArray (rptr :: Ptr Word8) (replicate 32 0)
fe_frombytes ptrc ptra
b <- convertFE ptrc
fe_tobytes (castPtr rptr) ptrc
start <- peek ptra
end <- peek (castPtr rptr)
unless (start == end) $
fail "field element tobytes/frombytes doesn't round trip"
bytes' <- pack `fmap` peekArray 32 (castPtr ptra :: Ptr Word8)
let res = Map.fromList [("a", showBin bytes'),
("b", showBin b)]
return (res, toNumber b, (memory0, drg1))
addsubTests :: Task
addsubTests = Task {
taskName = "ed25519 addition/subtraction tests",
taskFile = "../testdata/ed25519/addsub.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ ptrel1 drg1 ->
randomElement drg1 $ \ ptrel2 drg2 ->
alloca $ \ ptrc ->
alloca $ \ ptrd ->
do fe_add ptrc ptrel1 ptrel2
fe_sub ptrd ptrel1 ptrel2
[a, b, c, d] <- mapM convertFE [ptrel1, ptrel2, ptrc, ptrd]
let res = Map.fromList [("a", showBin a),
("b", showBin b),
("c", showBin c),
("d", showBin d)]
return (res, toNumber c, (memory0, drg2))
mulTests :: Task
mulTests = Task {
taskName = "ed25519 multiplication tests",
taskFile = "../testdata/ed25519/mul.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ ptrel1 drg1 ->
randomElement drg1 $ \ ptrel2 drg2 ->
alloca $ \ ptrc ->
do fe_mul ptrc ptrel1 ptrel2
[a, b, c] <- mapM convertFE [ptrel1, ptrel2, ptrc]
let res = Map.fromList [("a", showBin a),
("b", showBin b),
("c", showBin c)]
return (res, toNumber c, (memory0, drg2))
squaringTests :: Task
squaringTests = Task {
taskName = "ed25519 squaring tests",
taskFile = "../testdata/ed25519/square.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ ptrel drg1 ->
alloca $ \ ptrc ->
do fe_square ptrc ptrel
[a, c] <- mapM convertFE [ptrel, ptrc]
let res = Map.fromList [("a", showBin a),
("c", showBin c)]
return (res, toNumber c, (memory0, drg1))
inversionTests :: Task
inversionTests = Task {
taskName = "ed25519 inversion tests",
taskFile = "../testdata/ed25519/invert.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ ptrel drg1 ->
alloca $ \ ptrc ->
do fe_invert ptrc ptrel
a <- convertFE ptrel
c <- convertFE ptrc
let res = Map.fromList [("a", showBin a),
("c", showBin c)]
return (res, toNumber a, (memory0, drg1))
negateTests :: Task
negateTests = Task {
taskName = "ed25519 negation tests",
taskFile = "../testdata/ed25519/negate.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ ptrel drg1 ->
alloca $ \ ptrc ->
do fe_negate ptrc ptrel
a <- convertFE ptrel
c <- convertFE ptrc
let res = Map.fromList [("a", showBin a),
("c", showBin c)]
return (res, toNumber a, (memory0, drg1))
cmovTests :: Task
cmovTests = Task {
taskName = "ed25519 conditional mov tests",
taskFile = "../testdata/ed25519/cmov.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ aelptr drg1 ->
do let (bbytes, drg2) = withDRG drg1 (getRandomBytes 1)
b = even (BS.head bbytes)
bvalLib = if b then 0 else 1
bvalOut = if b then 0 else 0xFFFFFF :: Word32
alloca $ \ celptr ->
do clearSpace celptr
fe_cmov celptr aelptr bvalLib
a <- convertFE aelptr
c <- convertFE celptr
let res = Map.fromList [("a", showBin a),
("b", showX bvalOut),
("c", showBin c)]
return (res, toNumber a, (memory0, drg2))
isTests :: Task
isTests = Task {
taskName = "ed25519 predicate tests",
taskFile = "../testdata/ed25519/istests.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ aptr drg1 ->
do a <- convertFE aptr
z <- fe_isnonzero aptr
n <- fe_isnegative aptr
let res = Map.fromList [("a", showBin a),
("z", showX (if z == 0 then 0 :: Word32 else 0xFFFFFF)),
("n", showX (if n == 0 then 0 :: Word32 else 0xFFFFFF))]
return (res, toNumber a, (memory0, drg1))
square2Tests :: Task
square2Tests = Task {
taskName = "ed25519 square2 tests",
taskFile = "../testdata/ed25519/square2.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ aptr drg1 ->
alloca $ \ cptr ->
do clearSpace cptr
fe_square2 cptr aptr
a <- convertFE aptr
c <- convertFE cptr
let res = Map.fromList [("a", showBin a), ("c", showBin c)]
return (res, toNumber a, (memory0, drg1))
pow22523Tests :: Task
pow22523Tests = Task {
taskName = "ed25519 pow22523 tests",
taskFile = "../testdata/ed25519/pow22523.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomElement drg0 $ \ aptr drg1 ->
alloca $ \ cptr ->
do clearSpace cptr
fe_pow22523 cptr aptr
a <- convertFE aptr
c <- convertFE cptr
let res = Map.fromList [("a", showBin a), ("c", showBin c)]
return (res, toNumber a, (memory0, drg1))
fbvTests :: Task
fbvTests = Task {
taskName = "ed25519 from bytes (vartime) tests",
taskFile = "../testdata/ed25519/fbv.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
do let (abytes, drg1) = withDRG drg0 (getRandomBytes 32)
useAsCString abytes $ \ aptr ->
do let aptr' = castPtr aptr :: Ptr PackedBytes
curve25519_scalar_mask aptr'
alloca $ \ dest ->
do clearSpace dest
point_frombytes dest aptr'
a <- pack `fmap` peekArray 32 (castPtr aptr)
c <- pack `fmap` peekArray (4 * 10 * 4) (castPtr dest)
let res = Map.fromList [("a", showBin a), ("c", showBin c)]
return (res, toNumber abytes, (memory0, drg1))
conversionTests :: Task
conversionTests = Task {
taskName = "ed25519 point form conversion tests",
taskFile = "../testdata/ed25519/conversion.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPoint3 drg0 $ \ ptr3 drg' ->
alloca $ \ ptrCached ->
alloca $ \ ptr2 ->
alloca $ \ ptrP1P1 ->
alloca $ \ ptr2' ->
alloca $ \ ptr3' ->
do clearSpace ptrCached
clearSpace ptr2
clearSpace ptrP1P1
clearSpace ptr2'
clearSpace ptr3'
p3_to_cached ptrCached ptr3
ge_p3_to_p2 ptr2 ptr3
ge_p3_dbl ptrP1P1 ptr3
p1p1_to_p2 ptr2' ptrP1P1
p1p1_to_p3 ptr3' ptrP1P1
a <- convertPoint ptr3
c <- convertPoint ptrCached
t <- convertPoint ptr2
o <- convertPoint ptrP1P1
d <- convertPoint ptr2'
b <- convertPoint ptr3'
let res = Map.fromList [("a", showBin a), ("c", showBin c),
("t", showBin t), ("o", showBin o),
("d", showBin d), ("b", showBin b)]
return (res, toNumber a, (memory0, drg'))
ptDoubleTests :: Task
ptDoubleTests = Task {
taskName = "ed25519 point doubling tests",
taskFile = "../testdata/ed25519/pt_double.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPoint3 drg0 $ \ ptra drg1 ->
randomPoint2 drg1 $ \ ptrc drg2 ->
alloca $ \ ptrb ->
alloca $ \ ptrd ->
do clearSpace ptrb
clearSpace ptrd
ge_p3_dbl ptrb ptra
ge_p2_dbl ptrd ptrc
a <- convertPoint ptra
b <- convertPoint ptrb
c <- convertPoint ptrc
d <- convertPoint ptrd
let res = Map.fromList [("a", showBin a), ("b", showBin b),
("c", showBin c), ("d", showBin d)]
return (res, toNumber a, (memory0, drg2))
maddsubTests :: Task
maddsubTests = Task {
taskName = "ed25519 point madd/msub tests",
taskFile = "../testdata/ed25519/maddsub.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPoint3 drg0 $ \ ptra drg1 ->
randomPointPrecomp drg1 $ \ ptrc drg2 ->
alloca $ \ ptrb ->
alloca $ \ ptrd ->
do clearSpace ptrb
clearSpace ptrd
ge_madd ptrb ptra ptrc
ge_msub ptrd ptra ptrc
a <- convertPoint ptra
b <- convertPoint ptrb
c <- convertPoint ptrc
d <- convertPoint ptrd
let res = Map.fromList [("a", showBin a), ("b", showBin b),
("c", showBin c), ("d", showBin d)]
return (res, toNumber a, (memory0, drg2))
ptAddSubTests :: Task
ptAddSubTests = Task {
taskName = "ed25519 point add/sub tests",
taskFile = "../testdata/ed25519/ptaddsub.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPoint3 drg0 $ \ ptra drg1 ->
randomPointCached drg1 $ \ ptrc drg2 ->
alloca $ \ ptrb ->
alloca $ \ ptrd ->
do clearSpace ptrb
clearSpace ptrd
ge_add ptrb ptra ptrc
ge_sub ptrd ptra ptrc
a <- convertPoint ptra
b <- convertPoint ptrb
c <- convertPoint ptrc
d <- convertPoint ptrd
let res = Map.fromList [("a", showBin a), ("b", showBin b),
("c", showBin c), ("d", showBin d)]
return (res, toNumber a, (memory0, drg2))
scalarMultBaseTests :: Task
scalarMultBaseTests = Task {
taskName = "ed25519 point add/sub tests",
taskFile = "../testdata/ed25519/scalar_mult.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPackedBytes drg0 $ \ ptra drg1 ->
alloca $ \ ptrb ->
do clearSpace ptrb
x25519_ge_scalarmult_base ptrb ptra
PB abytes <- peek ptra
let a = pack abytes
b <- convertPoint ptrb
let res = Map.fromList [("a", showBin a), ("b", showBin b)]
return (res, toNumber a, (memory0, drg1))
slideTests :: Task
slideTests = Task {
taskName = "ed25519 slide helper function tests",
taskFile = "../testdata/ed25519/slide.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPackedBytes drg0 $ \ ptra drg1 ->
allocaArray 256 $ \ ptrb ->
do pokeArray ptrb (replicate 256 0)
slide ptrb ptra
a <- pack `fmap` peekArray 32 (castPtr ptra)
b <- pack `fmap` peekArray 356 ptrb
let res = Map.fromList [("a", showBin a), ("b", showBin b)]
return (res, toNumber a, (memory0, drg1))
scalarMultTests :: Task
scalarMultTests = Task {
taskName = "ed25519 point general scalar multiplication tests",
taskFile = "../testdata/ed25519/scalar_mult_gen.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPackedBytes drg0 $ \ ptra drg1 ->
randomPoint3 drg1 $ \ ptrb drg2 ->
randomPackedBytes drg2 $ \ ptrc drg3 ->
alloca $ \ ptrd ->
do clearSpace ptrd
ge_double_scalarmult_vartime ptrd ptra ptrb ptrc
PB abytes <- peek ptra
let a = pack abytes
b <- convertPoint ptrb
PB cbytes <- peek ptrc
let c = pack cbytes
d <- convertPoint ptrd
let res = Map.fromList [("a", showBin a), ("b", showBin b),
("c", showBin c), ("d", showBin d)]
return (res, toNumber a, (memory0, drg3))
reduceTests :: Task
reduceTests = Task {
taskName = "ed25519 reduce tests",
taskFile = "../testdata/ed25519/reduce.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
do let (a, drg1) = withDRG drg0 (getRandomBytes 64)
allocaArray 64 $ \ target ->
do pokeArray target (BS.unpack a)
sc_reduce target
b <- pack `fmap` peekArray 32 target
let res = Map.fromList [("a", showBin a), ("b", showBin b)]
return (res, toNumber a, (memory0, drg1))
muladdTests :: Task
muladdTests = Task {
taskName = "ed25519 multiplication+addition tests",
taskFile = "../testdata/ed25519/muladd.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPackedBytes drg0 $ \ ptra drg1 ->
randomPackedBytes drg1 $ \ ptrb drg2 ->
randomPackedBytes drg2 $ \ ptrc drg3 ->
alloca $ \ ptrd ->
do clearSpace ptrd
sc_muladd ptrd ptra ptrb ptrc
a <- repackBytes ptra
b <- repackBytes ptrb
c <- repackBytes ptrc
d <- repackBytes ptrd
let res = Map.fromList [("a", showBin a), ("b", showBin b),
("c", showBin c), ("d", showBin d)]
return (res, toNumber a, (memory0, drg3))
pubPrivTests :: Task
pubPrivTests = Task {
taskName = "ed25519 private -> public conversion tests",
taskFile = "../testdata/ed25519/pubfrompriv.test",
taskTest = go,
taskCount = cTEST_COUNT
}
where
go (memory0, drg0) =
randomPackedBytes drg0 $ \ ptra drg1 ->
alloca $ \ ptrb ->
do clearSpace ptrb
public_from_private ptrb ptra
a <- repackBytes ptra
b <- repackBytes ptrb
let res = Map.fromList [("a", showBin a), ("b", showBin b)]
return (res, toNumber a, (memory0, drg1))
data PackedBytes = PB [Word8]
deriving (Eq)
instance Storable PackedBytes where
sizeOf _ = 32
alignment _ = 8
peek p = PB `fmap` peekArray 32 (castPtr p)
poke p (PB v) = pokeArray (castPtr p) v
randomPackedBytes :: SystemRandom -> (Ptr PackedBytes -> SystemRandom -> IO a) -> IO a
randomPackedBytes drg action =
do let (bytes, drg') = withDRG drg (getRandomBytes 32)
useAsCString bytes $ \ ptr ->
do let ptr' = castPtr ptr :: Ptr PackedBytes
curve25519_scalar_mask ptr'
action ptr' drg'
repackBytes :: Ptr PackedBytes -> IO ByteString
repackBytes ptr =
do PB xs <- peek ptr
return (pack xs)
data Element = FE [Int32]
instance Storable Element where
sizeOf _ = 10 * sizeOf (undefined :: Int32)
alignment _ = 8
peek p = FE `fmap` peekArray 10 (castPtr p)
poke p (FE v) = pokeArray (castPtr p) v
randomElement :: SystemRandom -> (Ptr Element -> SystemRandom -> IO a) -> IO a
randomElement drg action =
randomPackedBytes drg $ \ ptrpb drg' -> alloca $ \ ptrel ->
do clearSpace ptrel
fe_frombytes ptrel ptrpb
action ptrel drg'
data Point3 = P3 [Element]
instance Storable Point3 where
sizeOf _ = 4 * sizeOf (undefined :: Element)
alignment _ = 8
peek p = P3 `fmap` peekArray 4 (castPtr p)
poke p (P3 v) = pokeArray (castPtr p) v
randomPoint3 :: SystemRandom -> (Ptr Point3 -> SystemRandom -> IO a) -> IO a
randomPoint3 drg action =
randomPackedBytes drg $ \ aptr drg' ->
allocaArray (4 * 10) $ \ dest ->
do clearSpace dest
point_frombytes dest aptr
action (castPtr dest) drg'
data PointCached = PC [Element]
instance Storable PointCached where
sizeOf _ = 4 * sizeOf (undefined :: Element)
alignment _ = 8
peek p = PC `fmap` peekArray 4 (castPtr p)
poke p (PC v) = pokeArray (castPtr p) v
randomPointCached :: SystemRandom -> (Ptr PointCached -> SystemRandom -> IO a) -> IO a
randomPointCached drg action =
randomPoint3 drg $ \ ptr drg' ->
allocaArray (4 * 10) $ \ dest ->
do pokeArray (castPtr dest :: Ptr Int32) (replicate (4 * 10) 0)
p3_to_cached dest ptr
action (castPtr dest) drg'
data Point2 = P2 [Element]
instance Storable Point2 where
sizeOf _ = 3 * sizeOf (undefined :: Element)
alignment _ = 8
peek p = P2 `fmap` peekArray 3 (castPtr p)
poke p (P2 v) = pokeArray (castPtr p) v
randomPoint2 :: SystemRandom -> (Ptr Point2 -> SystemRandom -> IO a) -> IO a
randomPoint2 drg action =
randomPoint3 drg $ \ ptr3 drg' ->
allocaArray (3 * 10) $ \ dest ->
do pokeArray (castPtr dest :: Ptr Int32) (replicate (3 * 10) 0)
ge_p3_to_p2 dest ptr3
action (castPtr dest) drg'
data PointP1P1 = P1P1 [Element]
instance Storable PointP1P1 where
sizeOf _ = 4 * sizeOf (undefined :: Element)
alignment _ = 8
peek p = P1P1 `fmap` peekArray 4 (castPtr p)
poke p (P1P1 v) = pokeArray (castPtr p) v
_randomPointP1P1 :: SystemRandom -> (Ptr PointP1P1 -> SystemRandom -> IO a) -> IO a
_randomPointP1P1 drg action =
randomPoint3 drg $ \ ptr3 drg' ->
allocaArray (4 * 10) $ \ dest ->
do pokeArray (castPtr dest :: Ptr Int32) (replicate (4 * 10) 0)
ge_p3_dbl dest ptr3
action (castPtr dest) drg'
data PointPrecomp = PP [Element]
instance Storable PointPrecomp where
sizeOf _ = 4 * sizeOf (undefined :: Element)
alignment _ = 8
peek p = PP `fmap` peekArray 4 (castPtr p)
poke p (PP v) = pokeArray (castPtr p) v
randomPointPrecomp :: SystemRandom -> (Ptr PointPrecomp -> SystemRandom -> IO a) -> IO a
randomPointPrecomp drg action =
do let ([a,b,c,d], drg') = withDRG drg (BS.unpack `fmap` getRandomBytes 4)
mix = fromIntegral a + fromIntegral b + fromIntegral c + fromIntegral d
idx = mix `mod` (length precompPoints)
val = PP (map FE (precompPoints !! idx))
alloca $ \ ptr ->
do poke ptr val
action ptr drg'
clearSpace :: Storable a => Ptr a -> IO ()
clearSpace x = meh x undefined
where
meh :: Storable a => Ptr a -> a -> IO ()
meh p v = pokeArray (castPtr p) (replicate (sizeOf v) (0 :: Word8))
convertFE :: Ptr Element -> IO ByteString
convertFE feptr = pack `fmap` peekArray 40 (castPtr feptr :: Ptr Word8)
convertPoint :: Storable a => Ptr a -> IO ByteString
convertPoint x = meh x undefined
where
meh :: Storable a => Ptr a -> a -> IO ByteString
meh p v = pack `fmap` peekArray (sizeOf v) (castPtr p)
toNumber :: ByteString -> Integer
toNumber = BS.foldr (\ x a -> fromIntegral x + a) 0
foreign import ccall unsafe "load_3"
load_3 :: Ptr CChar -> IO Word64
foreign import ccall unsafe "load_4"
load_4 :: Ptr CChar -> IO Word64
foreign import ccall unsafe "GFp_curve25519_scalar_mask"
curve25519_scalar_mask :: Ptr PackedBytes -> IO ()
foreign import ccall unsafe "fe_frombytes"
fe_frombytes :: Ptr Element -> Ptr PackedBytes -> IO ()
foreign import ccall unsafe "GFp_fe_tobytes"
fe_tobytes :: Ptr PackedBytes -> Ptr Element -> IO ()
foreign import ccall unsafe "fe_add"
fe_add :: Ptr Element -> Ptr Element -> Ptr Element -> IO ()
foreign import ccall unsafe "fe_sub"
fe_sub :: Ptr Element -> Ptr Element -> Ptr Element -> IO ()
foreign import ccall unsafe "GFp_fe_mul"
fe_mul :: Ptr Element -> Ptr Element -> Ptr Element -> IO ()
foreign import ccall unsafe "fe_sq"
fe_square :: Ptr Element -> Ptr Element -> IO ()
foreign import ccall unsafe "GFp_fe_invert"
fe_invert :: Ptr Element -> Ptr Element -> IO ()
foreign import ccall unsafe "fe_neg"
fe_negate :: Ptr Element -> Ptr Element -> IO ()
foreign import ccall unsafe "fe_cmov"
fe_cmov :: Ptr Element -> Ptr Element -> Word32 -> IO ()
foreign import ccall unsafe "fe_isnonzero"
fe_isnonzero :: Ptr Element -> IO Int32
foreign import ccall unsafe "GFp_fe_isnegative"
fe_isnegative :: Ptr Element -> IO Word8
foreign import ccall unsafe "fe_sq2"
fe_square2 :: Ptr Element -> Ptr Element -> IO ()
foreign import ccall unsafe "fe_pow22523"
fe_pow22523 :: Ptr Element -> Ptr Element -> IO ()
foreign import ccall unsafe "GFp_x25519_ge_frombytes_vartime"
point_frombytes :: Ptr Point3 -> Ptr PackedBytes -> IO ()
foreign import ccall unsafe "x25519_ge_p3_to_cached"
p3_to_cached :: Ptr PointCached -> Ptr Point3 -> IO ()
foreign import ccall unsafe "x25519_ge_p1p1_to_p2"
p1p1_to_p2 :: Ptr Point2 -> Ptr PointP1P1 -> IO ()
foreign import ccall unsafe "x25519_ge_p1p1_to_p3"
p1p1_to_p3 :: Ptr Point3 -> Ptr PointP1P1 -> IO ()
foreign import ccall unsafe "ge_p2_dbl"
ge_p2_dbl :: Ptr PointP1P1 -> Ptr Point2 -> IO ()
foreign import ccall unsafe "ge_p3_dbl"
ge_p3_dbl :: Ptr PointP1P1 -> Ptr Point3 -> IO ()
foreign import ccall unsafe "ge_p3_to_p2"
ge_p3_to_p2 :: Ptr Point2 -> Ptr Point3 -> IO ()
foreign import ccall unsafe "ge_madd"
ge_madd :: Ptr PointP1P1 -> Ptr Point3 -> Ptr PointPrecomp -> IO ()
foreign import ccall unsafe "ge_msub"
ge_msub :: Ptr PointP1P1 -> Ptr Point3 -> Ptr PointPrecomp -> IO ()
foreign import ccall unsafe "x25519_ge_add"
ge_add :: Ptr PointP1P1 -> Ptr Point3 -> Ptr PointCached -> IO ()
foreign import ccall unsafe "x25519_ge_sub"
ge_sub :: Ptr PointP1P1 -> Ptr Point3 -> Ptr PointCached -> IO ()
foreign import ccall unsafe "GFp_x25519_ge_scalarmult_base"
x25519_ge_scalarmult_base :: Ptr Point3 -> Ptr PackedBytes -> IO ()
foreign import ccall unsafe "slide"
slide :: Ptr Word8 -> Ptr PackedBytes -> IO ()
foreign import ccall unsafe "GFp_ge_double_scalarmult_vartime"
ge_double_scalarmult_vartime :: Ptr Point2 -> Ptr PackedBytes -> Ptr Point3 -> Ptr PackedBytes -> IO ()
foreign import ccall unsafe "GFp_x25519_sc_reduce"
sc_reduce :: Ptr Word8 -> IO ()
foreign import ccall unsafe "GFp_x25519_sc_muladd"
sc_muladd :: Ptr PackedBytes -> Ptr PackedBytes -> Ptr PackedBytes -> Ptr PackedBytes -> IO ()
foreign import ccall unsafe "GFp_x25519_public_from_private"
public_from_private :: Ptr PackedBytes -> Ptr PackedBytes -> IO ()

File diff suppressed because it is too large Load Diff

View File

@@ -8,6 +8,7 @@ import Control.Monad(replicateM_,void)
import "crypto-api" Crypto.Random(CryptoRandomGen(..),SystemRandom)
import DSA(dsaTasks)
import ECDSATesting(ecdsaTasks)
import ED25519(ed25519Tasks)
import GHC.Conc(getNumCapabilities)
import RFC6979(rfcTasks)
import RSA(rsaTasks)
@@ -38,6 +39,6 @@ main = displayConsoleRegions $
do
executors <- getNumCapabilities
done <- newChan
tasks <- newMVar (dsaTasks ++ ecdsaTasks ++ rfcTasks ++ rsaTasks)
tasks <- newMVar (dsaTasks ++ ecdsaTasks ++ rfcTasks ++ rsaTasks ++ ed25519Tasks)
replicateM_ executors (spawnExecutor tasks done)
replicateM_ executors (void $ readChan done)

View File

@@ -0,0 +1,96 @@
/* ====================================================================
* Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
#ifndef OPENSSL_HEADER_AES_H
#define OPENSSL_HEADER_AES_H
#include <GFp/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Raw AES functions. */
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
/* AES_MAXNR is the maximum number of AES rounds. */
#define AES_MAXNR 14
#define AES_BLOCK_SIZE 16
/* aes_key_st should be an opaque type, but EVP requires that the size be
* known. */
struct aes_key_st {
uint32_t rd_key[4 * (AES_MAXNR + 1)];
unsigned rounds;
};
typedef struct aes_key_st AES_KEY;
/* GFp_AES_set_encrypt_key configures |aeskey| to encrypt with the |bits|-bit
* key, |key|.
*
* WARNING: unlike other OpenSSL functions, this returns zero on success and a
* negative number on error. */
OPENSSL_EXPORT int GFp_AES_set_encrypt_key(const uint8_t *key, unsigned bits,
AES_KEY *aeskey);
/* AES_encrypt encrypts a single block from |in| to |out| with |key|. The |in|
* and |out| pointers may overlap. */
OPENSSL_EXPORT void GFp_AES_encrypt(const uint8_t *in, uint8_t *out,
const AES_KEY *key);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_AES_H */

View File

@@ -0,0 +1,123 @@
/* ====================================================================
* Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#ifndef OPENSSL_HEADER_ARM_ARCH_H
#define OPENSSL_HEADER_ARM_ARCH_H
#if !defined(__ARM_ARCH__)
# if defined(__CC_ARM)
# define __ARM_ARCH__ __TARGET_ARCH_ARM
# if defined(__BIG_ENDIAN)
# define __ARMEB__
# else
# define __ARMEL__
# endif
# elif defined(__GNUC__)
# if defined(__aarch64__)
# define __ARM_ARCH__ 8
# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define __ARMEB__
# else
# define __ARMEL__
# endif
/* Why doesn't gcc define __ARM_ARCH__? Instead it defines
* bunch of below macros. See all_architectires[] table in
* gcc/config/arm/arm.c. On a side note it defines
* __ARMEL__/__ARMEB__ for little-/big-endian. */
# elif defined(__ARM_ARCH)
# define __ARM_ARCH__ __ARM_ARCH
# elif defined(__ARM_ARCH_8A__)
# define __ARM_ARCH__ 8
# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
defined(__ARM_ARCH_7EM__)
# define __ARM_ARCH__ 7
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \
defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \
defined(__ARM_ARCH_6T2__)
# define __ARM_ARCH__ 6
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \
defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \
defined(__ARM_ARCH_5TEJ__)
# define __ARM_ARCH__ 5
# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
# define __ARM_ARCH__ 4
# else
# error "unsupported ARM architecture"
# endif
# endif
#endif
/* Even when building for 32-bit ARM, support for aarch64 crypto instructions
* will be included. */
#if !defined(__ARM_MAX_ARCH__)
#define __ARM_MAX_ARCH__ 8
#endif
/* ARMV7_NEON is true when a NEON unit is present in the current CPU. */
#define ARMV7_NEON (1 << 0)
/* ARMV8_AES indicates support for hardware AES instructions. */
#define ARMV8_AES (1 << 2)
/* ARMV8_SHA1 indicates support for hardware SHA-1 instructions. */
#define ARMV8_SHA1 (1 << 3)
/* ARMV8_SHA256 indicates support for hardware SHA-256 instructions. */
#define ARMV8_SHA256 (1 << 4)
/* ARMV8_PMULL indicates support for carryless multiplication. */
#define ARMV8_PMULL (1 << 5)
#endif /* OPENSSL_HEADER_ARM_ARCH_H */

View File

@@ -0,0 +1,122 @@
/* ====================================================================
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#ifndef OPENSSL_HEADER_BASE_H
#define OPENSSL_HEADER_BASE_H
/* This file should be the first included by all BoringSSL headers. */
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64)
#define OPENSSL_64_BIT
#define OPENSSL_X86_64
#elif defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86)
#define OPENSSL_32_BIT
#define OPENSSL_X86
#elif defined(__aarch64__)
#define OPENSSL_64_BIT
#define OPENSSL_AARCH64
#elif defined(__arm) || defined(__arm__) || defined(_M_ARM)
#define OPENSSL_32_BIT
#define OPENSSL_ARM
#elif (defined(__PPC64__) || defined(__powerpc64__)) && defined(_LITTLE_ENDIAN)
#define OPENSSL_64_BIT
#define OPENSSL_PPC64LE
#elif defined(__mips__) && !defined(__LP64__)
#define OPENSSL_32_BIT
#define OPENSSL_MIPS
#elif defined(__mips__) && defined(__LP64__)
#define OPENSSL_64_BIT
#define OPENSSL_MIPS64
#elif defined(__pnacl__)
#define OPENSSL_32_BIT
#define OPENSSL_PNACL
#elif defined(__myriad2__)
#define OPENSSL_32_BIT
#else
#error "Unknown target CPU"
#endif
#if defined(__APPLE__)
#define OPENSSL_APPLE
#endif
#if defined(_WIN32)
#define OPENSSL_WINDOWS
#endif
#define OPENSSL_IS_BORINGSSL
#define OPENSSL_IS_RING
#define OPENSSL_VERSION_NUMBER 0x10002000
/* *ring* doesn't support the `BORINGSSL_SHARED_LIBRARY` configuration, so
* the default (usually "hidden") visibility is always used, even for exported
* items. */
#define OPENSSL_EXPORT
typedef struct bignum_st BIGNUM;
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_BASE_H */

View File

@@ -0,0 +1,256 @@
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
* Laboratories. */
#ifndef OPENSSL_HEADER_BN_H
#define OPENSSL_HEADER_BN_H
#include <GFp/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* BN provides support for working with arbitrary sized integers. For example,
* although the largest integer supported by the compiler might be 64 bits, BN
* will allow you to work with numbers until you run out of memory. */
/* BN_ULONG is the native word size when working with big integers.
*
* Note: on some platforms, inttypes.h does not define print format macros in
* C++ unless |__STDC_FORMAT_MACROS| defined. As this is a public header, bn.h
* does not define |__STDC_FORMAT_MACROS| itself. C++ source files which use the
* FMT macros must define it externally. */
#if defined(OPENSSL_64_BIT)
#define BN_ULONG uint64_t
#define BN_BITS2 64
#elif defined(OPENSSL_32_BIT)
#define BN_ULONG uint32_t
#define BN_BITS2 32
#else
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
#endif
/* Allocation and freeing. */
/* GFp_BN_init initialises a stack allocated |BIGNUM|. */
OPENSSL_EXPORT void GFp_BN_init(BIGNUM *bn);
/* GFp_BN_free frees the data referenced by |bn| and, if |bn| was originally
* allocated on the heap, frees |bn| also. */
OPENSSL_EXPORT void GFp_BN_free(BIGNUM *bn);
/* GFp_BN_copy sets |dest| equal to |src| and returns one on success or zero on
* failure. */
OPENSSL_EXPORT int GFp_BN_copy(BIGNUM *dest, const BIGNUM *src);
/* Basic functions. */
/* GFp_BN_zero sets |bn| to zero. */
OPENSSL_EXPORT void GFp_BN_zero(BIGNUM *bn);
/* Internal functions.
*
* These functions are useful for code that is doing low-level manipulations of
* BIGNUM values. However, be sure that no other function in this file does
* what you want before turning to these. */
/* bn_correct_top decrements |bn->top| until |bn->d[top-1]| is non-zero or
* until |top| is zero. */
OPENSSL_EXPORT void GFp_bn_correct_top(BIGNUM *bn);
/* bn_wexpand ensures that |bn| has at least |words| works of space without
* altering its value. It returns one on success and zero on allocation
* failure. */
OPENSSL_EXPORT int GFp_bn_wexpand(BIGNUM *bn, size_t words);
/* Simple arithmetic */
/* GFp_BN_mul_no_alias sets |r| = |a| * |b|, where |r| must not be the same pointer
* as |a| or |b|. Returns one on success and zero otherwise. */
OPENSSL_EXPORT int GFp_BN_mul_no_alias(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
/* Comparison functions */
/* GFp_BN_is_odd returns one if |bn| is odd and zero otherwise. */
OPENSSL_EXPORT int GFp_BN_is_odd(const BIGNUM *bn);
/* Bitwise operations. */
/* GFp_BN_is_bit_set returns the value of the |n|th, least-significant bit in
* |a|, or zero if the bit doesn't exist. */
OPENSSL_EXPORT int GFp_BN_is_bit_set(const BIGNUM *a, int n);
/* Modulo arithmetic. */
/* GFp_BN_mod_mul_mont set |r| equal to |a| * |b|, in the Montgomery domain.
* Both |a| and |b| must already be in the Montgomery domain (by
* |GFp_BN_to_mont|). In particular, |a| and |b| are assumed to be in the range
* [0, n), where |n| is the Montgomery modulus. It returns one on success or
* zero on error. */
OPENSSL_EXPORT int GFp_BN_mod_mul_mont(
BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *n,
const BN_ULONG n0[/*BN_MONT_CTX_N0_LIMBS*/]);
/* GFp_BN_reduce_montgomery returns |a % n| in constant-ish time using
* Montgomery reduction. |a| is assumed to be in the range [0, n**2), where |n|
* is the Montgomery modulus. It returns one on success or zero on error. */
int GFp_BN_reduce_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *n,
const BN_ULONG n0[/*BN_MONT_CTX_N0_LIMBS*/]);
/* Exponentiation. */
OPENSSL_EXPORT int GFp_BN_mod_exp_mont_consttime(
BIGNUM *rr, const BIGNUM *a_mont, const BIGNUM *p, size_t p_bits,
const BIGNUM *one_mont, const BIGNUM *n,
const BN_ULONG n0[/*BN_MONT_CTX_N0_LIMBS*/]);
/* Private functions */
/* Keep in sync with `BIGNUM` in `ring::rsa::bigint`. */
struct bignum_st {
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks in little-endian
order. */
int top; /* Index of last used element in |d|, plus one. */
int dmax; /* Size of |d|, in words. */
int flags; /* bitmask of BN_FLG_* values */
};
#define BN_FLG_MALLOCED 0x01
#define BN_FLG_STATIC_DATA 0x02
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_BN_H */

View File

@@ -0,0 +1,189 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#ifndef OPENSSL_HEADER_CPU_H
#define OPENSSL_HEADER_CPU_H
#include <GFp/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Runtime CPU feature support */
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
/* GFp_ia32cap_P contains the Intel CPUID bits when running on an x86 or
* x86-64 system.
*
* Index 0:
* EDX for CPUID where EAX = 1
* Bit 20 is always zero
* Bit 28 is adjusted to reflect whether the data cache is shared between
* multiple logical cores
* Bit 30 is used to indicate an Intel CPU
* Index 1:
* ECX for CPUID where EAX = 1
* Bit 11 is used to indicate AMD XOP support, not SDBG
* Index 2:
* EBX for CPUID where EAX = 7
* Index 3 is set to zero.
*
* Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM
* bits in XCR0, so it is not necessary to check those. */
extern uint32_t GFp_ia32cap_P[4];
#endif
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
#if defined(OPENSSL_APPLE)
/* iOS builds use the static ARM configuration. */
#define OPENSSL_STATIC_ARMCAP
#if defined(OPENSSL_AARCH64)
#define OPENSSL_STATIC_ARMCAP_AES
#define OPENSSL_STATIC_ARMCAP_SHA1
#define OPENSSL_STATIC_ARMCAP_SHA256
#define OPENSSL_STATIC_ARMCAP_PMULL
#endif
#endif
#if !defined(OPENSSL_STATIC_ARMCAP)
/* GFp_is_NEON_capable_at_runtime returns true if the current CPU has a NEON
* unit. Note that |OPENSSL_armcap_P| also exists and contains the same
* information in a form that's easier for assembly to use. */
OPENSSL_EXPORT uint8_t GFp_is_NEON_capable_at_runtime(void);
/* GFp_is_NEON_capable returns true if the current CPU has a NEON unit. If
* this is known statically then it returns one immediately. */
static inline int GFp_is_NEON_capable(void) {
/* On 32-bit ARM, one CPU is known to have a broken NEON unit which is known
* to fail with on some hand-written NEON assembly. Assume that non-Android
* applications will not use that buggy CPU but still support Android users
* that do, even when the compiler is instructed to freely emit NEON code.
* See https://crbug.com/341598 and https://crbug.com/606629. */
#if defined(__ARM_NEON__) && (!defined(OPENSSL_ARM) || !defined(__ANDROID__))
return 1;
#else
return GFp_is_NEON_capable_at_runtime();
#endif
}
#if defined(OPENSSL_ARM)
/* GFp_has_broken_NEON returns one if the current CPU is known to have a
* broken NEON unit. See https://crbug.com/341598. */
OPENSSL_EXPORT int GFp_has_broken_NEON(void);
#endif
/* GFp_is_ARMv8_AES_capable returns true if the current CPU supports the
* ARMv8 AES instruction. */
int GFp_is_ARMv8_AES_capable(void);
/* GFp_is_ARMv8_PMULL_capable returns true if the current CPU supports the
* ARMv8 PMULL instruction. */
int GFp_is_ARMv8_PMULL_capable(void);
#else
static inline int GFp_is_NEON_capable(void) {
#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__)
return 1;
#else
return 0;
#endif
}
static inline int GFp_is_ARMv8_AES_capable(void) {
#if defined(OPENSSL_STATIC_ARMCAP_AES)
return 1;
#else
return 0;
#endif
}
static inline int GFp_is_ARMv8_PMULL_capable(void) {
#if defined(OPENSSL_STATIC_ARMCAP_PMULL)
return 1;
#else
return 0;
#endif
}
#endif /* OPENSSL_STATIC_ARMCAP */
#endif /* OPENSSL_ARM || OPENSSL_AARCH64 */
#if defined(OPENSSL_PPC64LE)
/* CRYPTO_is_PPC64LE_vcrypto_capable returns true iff the current CPU supports
* the Vector.AES category of instructions. */
int CRYPTO_is_PPC64LE_vcrypto_capable(void);
#endif /* OPENSSL_PPC64LE */
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_CPU_H */

View File

@@ -0,0 +1,93 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#ifndef OPENSSL_HEADER_MEM_H
#define OPENSSL_HEADER_MEM_H
#include <GFp/base.h>
#include <stdlib.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Memory and string functions, see also buf.h.
*
* OpenSSL has, historically, had a complex set of malloc debugging options.
* However, that was written in a time before Valgrind and ASAN. Since we now
* have those tools, the OpenSSL allocation functions are simply macros around
* the standard memory functions. */
#define OPENSSL_malloc malloc
#define OPENSSL_realloc realloc
#define OPENSSL_free free
/* GFp_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. It
* takes an amount of time dependent on |len|, but independent of the contents
* of |a| and |b|. Unlike memcmp, it cannot be used to put elements into a
* defined order as the return value when a != b is undefined, other than to be
* non-zero. */
OPENSSL_EXPORT int GFp_memcmp(const void *a, const void *b, size_t len);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_MEM_H */

View File

@@ -0,0 +1,75 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#ifndef OPENSSL_HEADER_TYPE_CHECK_H
#define OPENSSL_HEADER_TYPE_CHECK_H
#include <GFp/base.h>
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define OPENSSL_COMPILE_ASSERT(cond, msg) _Static_assert(cond, #msg)
#elif defined(__GNUC__)
#define OPENSSL_COMPILE_ASSERT(cond, msg) \
typedef char OPENSSL_COMPILE_ASSERT_##msg[((cond) ? 1 : -1)] \
__attribute__((unused))
#else
#define OPENSSL_COMPILE_ASSERT(cond, msg) \
typedef char OPENSSL_COMPILE_ASSERT_##msg[((cond) ? 1 : -1)]
#endif
#endif /* OPENSSL_HEADER_TYPE_CHECK_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
/* Copyright (c) 2015, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef OPENSSL_HEADER_CURVE25519_INTERNAL_H
#define OPENSSL_HEADER_CURVE25519_INTERNAL_H
#include <GFp/base.h>
#include <stdint.h>
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(OPENSSL_X86_64) && !defined(OPENSSL_SMALL) && \
!defined(OPENSSL_WINDOWS) && !defined(OPENSSL_NO_ASM)
/* This isn't compatible with Windows because the asm code makes use of the red
* zone, which Windows doesn't support. */
#define BORINGSSL_X25519_X86_64
void GFp_x25519_x86_64(uint8_t out[32], const uint8_t scalar[32],
const uint8_t point[32]);
#endif
#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM)
#define BORINGSSL_X25519_NEON
/* x25519_NEON is defined in asm/x25519-arm.S. */
void GFp_x25519_NEON(uint8_t out[32], const uint8_t scalar[32],
const uint8_t point[32]);
#endif
/* fe means field element. Here the field is \Z/(2^255-19). An element t,
* entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77
* t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on
* context.
*
* Keep in sync with `Elem` and `ELEM_LIMBS` in curve25519/ops.rs. */
typedef int32_t fe[10];
/* ge means group element.
* Here the group is the set of pairs (x,y) of field elements (see fe.h)
* satisfying -x^2 + y^2 = 1 + d x^2y^2
* where d = -121665/121666.
*
* Representations:
* ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z
* ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT
* ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T
* ge_precomp (Duif): (y+x,y-x,2dxy)
*/
/* Keep in sync with `Point` in curve25519/ops.rs. */
typedef struct {
fe X;
fe Y;
fe Z;
} ge_p2;
/* Keep in sync with `ExtPoint` in curve25519/ops.rs. */
typedef struct {
fe X;
fe Y;
fe Z;
fe T;
} ge_p3;
typedef struct {
fe X;
fe Y;
fe Z;
fe T;
} ge_p1p1;
typedef struct {
fe yplusx;
fe yminusx;
fe xy2d;
} ge_precomp;
typedef struct {
fe YplusX;
fe YminusX;
fe Z;
fe T2d;
} ge_cached;
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_CURVE25519_INTERNAL_H */

View File

@@ -0,0 +1,361 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#ifndef OPENSSL_HEADER_CRYPTO_INTERNAL_H
#define OPENSSL_HEADER_CRYPTO_INTERNAL_H
#include <assert.h>
#if defined(__clang__) || defined(_MSC_VER)
#include <string.h>
#endif
#include <stddef.h>
#include <GFp/base.h>
#include <GFp/type_check.h>
#if defined(_MSC_VER)
#pragma warning(push, 3)
#include <intrin.h>
#pragma warning(pop)
#if !defined(__cplusplus)
#define alignas(x) __declspec(align(x))
#define alignof __alignof
#endif
#elif !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 4 && \
__GNUC_MINOR__ <= 6
#define alignas(x) __attribute__((aligned (x)))
#define alignof __alignof__
#else
#include <stdalign.h>
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE)
/* OPENSSL_cpuid_setup initializes the platform-specific feature cache. */
void GFp_cpuid_setup(void);
#endif
#define OPENSSL_LITTLE_ENDIAN 1
#define OPENSSL_BIG_ENDIAN 2
#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define OPENSSL_ENDIAN OPENSSL_LITTLE_ENDIAN
#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define OPENSSL_ENDIAN OPENSSL_BIG_ENDIAN
#else
#error "Cannot determine endianness"
#endif
#if defined(__GNUC__)
#define bswap_u32(x) __builtin_bswap32(x)
#define bswap_u64(x) __builtin_bswap64(x)
#elif defined(_MSC_VER)
#pragma intrinsic(_byteswap_ulong, _byteswap_uint64)
#define bswap_u32(x) _byteswap_ulong(x)
#define bswap_u64(x) _byteswap_uint64(x)
#endif
#if !defined(_MSC_VER) && defined(OPENSSL_64_BIT)
typedef __int128_t int128_t;
typedef __uint128_t uint128_t;
#endif
/* Constant-time utility functions.
*
* The following methods return a bitmask of all ones (0xff...f) for true and 0
* for false. This is useful for choosing a value based on the result of a
* conditional in constant time. */
/* constant_time_msb returns the given value with the MSB copied to all the
* other bits. */
static inline unsigned int constant_time_msb_unsigned(unsigned int a) {
return (unsigned int)((int)(a) >> (sizeof(int) * 8 - 1));
}
OPENSSL_COMPILE_ASSERT(sizeof(ptrdiff_t) == sizeof(size_t),
ptrdiff_t_and_size_t_are_different_sizes);
static inline size_t constant_time_msb_size_t(size_t a) {
return (size_t)((ptrdiff_t)(a) >> (sizeof(ptrdiff_t) * 8 - 1));
}
/* constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise. */
static inline unsigned int constant_time_is_zero_unsigned(unsigned int a) {
/* Here is an SMT-LIB verification of this formula:
*
* (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32)
* (bvand (bvnot a) (bvsub a #x00000001))
* )
*
* (declare-fun a () (_ BitVec 32))
*
* (assert (not (= (= #x00000001 (bvlshr (is_zero a) #x0000001f)) (= a #x00000000))))
* (check-sat)
* (get-model)
*/
return constant_time_msb_unsigned(~a & (a - 1));
}
/* constant_time_is_zero_size_t is like |constant_time_is_zero_unsigned| but
* operates on |size_t|. */
static inline size_t constant_time_is_zero_size_t(size_t a) {
return constant_time_msb_size_t(~a & (a - 1));
}
static inline size_t constant_time_is_nonzero_size_t(size_t a) {
return constant_time_is_zero_size_t(constant_time_is_zero_size_t(a));
}
/* constant_time_eq_int returns 0xff..f if a == b and 0 otherwise. */
static inline unsigned int constant_time_eq_int(int a, int b) {
return constant_time_is_zero_unsigned((unsigned)(a) ^ (unsigned)(b));
}
/* constant_time_eq_size_t acts like |constant_time_eq_int| but operates on
* |size_t|. */
static inline size_t constant_time_eq_size_t(size_t a, size_t b) {
return constant_time_is_zero_size_t(a ^ b);
}
/* constant_time_select_size_t returns (mask & a) | (~mask & b). When |mask| is
* all 1s or all 0s (as returned by the methods above), the select methods
* return either |a| (if |mask| is nonzero) or |b| (if |mask| is zero). it is
* derived from BoringSSL's |constant_time_select|. */
static inline size_t constant_time_select_size_t(size_t mask, size_t a,
size_t b) {
return (mask & a) | (~mask & b);
}
/* from_be_u32_ptr returns the 32-bit big-endian-encoded value at |data|. */
static inline uint32_t from_be_u32_ptr(const uint8_t *data) {
#if defined(__clang__) || defined(_MSC_VER)
/* XXX: Unlike GCC, Clang doesn't optimize compliant access to unaligned data
* well. See https://llvm.org/bugs/show_bug.cgi?id=20605,
* https://llvm.org/bugs/show_bug.cgi?id=17603,
* http://blog.regehr.org/archives/702, and
* http://blog.regehr.org/archives/1055. MSVC seems to have similar problems.
*/
uint32_t value;
memcpy(&value, data, sizeof(value));
#if OPENSSL_ENDIAN != OPENSSL_BIG_ENDIAN
value = bswap_u32(value);
#endif
return value;
#else
return ((uint32_t)data[0] << 24) |
((uint32_t)data[1] << 16) |
((uint32_t)data[2] << 8) |
((uint32_t)data[3]);
#endif
}
/* from_be_u64_ptr returns the 64-bit big-endian-encoded value at |data|. */
static inline uint64_t from_be_u64_ptr(const uint8_t *data) {
#if defined(__clang__) || defined(_MSC_VER)
/* XXX: Unlike GCC, Clang doesn't optimize compliant access to unaligned data
* well. See https://llvm.org/bugs/show_bug.cgi?id=20605,
* https://llvm.org/bugs/show_bug.cgi?id=17603,
* http://blog.regehr.org/archives/702, and
* http://blog.regehr.org/archives/1055. MSVC seems to have similar problems.
*/
uint64_t value;
memcpy(&value, data, sizeof(value));
#if OPENSSL_ENDIAN != OPENSSL_BIG_ENDIAN
value = bswap_u64(value);
#endif
return value;
#else
return ((uint64_t)data[0] << 56) |
((uint64_t)data[1] << 48) |
((uint64_t)data[2] << 40) |
((uint64_t)data[3] << 32) |
((uint64_t)data[4] << 24) |
((uint64_t)data[5] << 16) |
((uint64_t)data[6] << 8) |
((uint64_t)data[7]);
#endif
}
/* to_be_u32_ptr writes the value |x| to the location |out| in big-endian
order. */
static inline void to_be_u32_ptr(uint8_t *out, uint32_t value) {
#if defined(__clang__) || defined(_MSC_VER)
/* XXX: Unlike GCC, Clang doesn't optimize compliant access to unaligned data
* well. See https://llvm.org/bugs/show_bug.cgi?id=20605,
* https://llvm.org/bugs/show_bug.cgi?id=17603,
* http://blog.regehr.org/archives/702, and
* http://blog.regehr.org/archives/1055. MSVC seems to have similar problems.
*/
#if OPENSSL_ENDIAN != OPENSSL_BIG_ENDIAN
value = bswap_u32(value);
#endif
memcpy(out, &value, sizeof(value));
#else
out[0] = (uint8_t)(value >> 24);
out[1] = (uint8_t)(value >> 16);
out[2] = (uint8_t)(value >> 8);
out[3] = (uint8_t)value;
#endif
}
/* to_be_u64_ptr writes the value |value| to the location |out| in big-endian
order. */
static inline void to_be_u64_ptr(uint8_t *out, uint64_t value) {
#if defined(__clang__) || defined(_MSC_VER)
/* XXX: Unlike GCC, Clang doesn't optimize compliant access to unaligned data
* well. See https://llvm.org/bugs/show_bug.cgi?id=20605,
* https://llvm.org/bugs/show_bug.cgi?id=17603,
* http://blog.regehr.org/archives/702, and
* http://blog.regehr.org/archives/1055. MSVC seems to have similar problems.
*/
#if OPENSSL_ENDIAN != OPENSSL_BIG_ENDIAN
value = bswap_u64(value);
#endif
memcpy(out, &value, sizeof(value));
#else
out[0] = (uint8_t)(value >> 56);
out[1] = (uint8_t)(value >> 48);
out[2] = (uint8_t)(value >> 40);
out[3] = (uint8_t)(value >> 32);
out[4] = (uint8_t)(value >> 24);
out[5] = (uint8_t)(value >> 16);
out[6] = (uint8_t)(value >> 8);
out[7] = (uint8_t)value;
#endif
}
/* from_be_u64 returns the native representation of the 64-bit
* big-endian-encoded value |x|. */
static inline uint64_t from_be_u64(uint64_t x) {
#if OPENSSL_ENDIAN != OPENSSL_BIG_ENDIAN
x = bswap_u64(x);
#endif
return x;
}
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_CRYPTO_INTERNAL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,244 @@
/* Copyright (c) 2015, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
/* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
* 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as
* public domain but this file has the ISC license just to keep licencing
* simple.
*
* The field functions are shared by Ed25519 and X25519 where possible. */
#include <string.h>
#include "internal.h"
#if defined(BORINGSSL_X25519_X86_64)
typedef struct { uint64_t v[5]; } fe25519;
/* These functions are defined in asm/x25519-x86_64.S */
void GFp_x25519_x86_64_work_cswap(fe25519 *, uint64_t);
void GFp_x25519_x86_64_mul(fe25519 *out, const fe25519 *a, const fe25519 *b);
void GFp_x25519_x86_64_square(fe25519 *out, const fe25519 *a);
void GFp_x25519_x86_64_freeze(fe25519 *);
void GFp_x25519_x86_64_ladderstep(fe25519 *work);
static void fe25519_setint(fe25519 *r, unsigned v) {
r->v[0] = v;
r->v[1] = 0;
r->v[2] = 0;
r->v[3] = 0;
r->v[4] = 0;
}
/* Assumes input x being reduced below 2^255 */
static void fe25519_pack(unsigned char r[32], const fe25519 *x) {
fe25519 t;
t = *x;
GFp_x25519_x86_64_freeze(&t);
r[0] = (uint8_t)(t.v[0] & 0xff);
r[1] = (uint8_t)((t.v[0] >> 8) & 0xff);
r[2] = (uint8_t)((t.v[0] >> 16) & 0xff);
r[3] = (uint8_t)((t.v[0] >> 24) & 0xff);
r[4] = (uint8_t)((t.v[0] >> 32) & 0xff);
r[5] = (uint8_t)((t.v[0] >> 40) & 0xff);
r[6] = (uint8_t)((t.v[0] >> 48));
r[6] ^= (uint8_t)((t.v[1] << 3) & 0xf8);
r[7] = (uint8_t)((t.v[1] >> 5) & 0xff);
r[8] = (uint8_t)((t.v[1] >> 13) & 0xff);
r[9] = (uint8_t)((t.v[1] >> 21) & 0xff);
r[10] = (uint8_t)((t.v[1] >> 29) & 0xff);
r[11] = (uint8_t)((t.v[1] >> 37) & 0xff);
r[12] = (uint8_t)((t.v[1] >> 45));
r[12] ^= (uint8_t)((t.v[2] << 6) & 0xc0);
r[13] = (uint8_t)((t.v[2] >> 2) & 0xff);
r[14] = (uint8_t)((t.v[2] >> 10) & 0xff);
r[15] = (uint8_t)((t.v[2] >> 18) & 0xff);
r[16] = (uint8_t)((t.v[2] >> 26) & 0xff);
r[17] = (uint8_t)((t.v[2] >> 34) & 0xff);
r[18] = (uint8_t)((t.v[2] >> 42) & 0xff);
r[19] = (uint8_t)((t.v[2] >> 50));
r[19] ^= (uint8_t)((t.v[3] << 1) & 0xfe);
r[20] = (uint8_t)((t.v[3] >> 7) & 0xff);
r[21] = (uint8_t)((t.v[3] >> 15) & 0xff);
r[22] = (uint8_t)((t.v[3] >> 23) & 0xff);
r[23] = (uint8_t)((t.v[3] >> 31) & 0xff);
r[24] = (uint8_t)((t.v[3] >> 39) & 0xff);
r[25] = (uint8_t)((t.v[3] >> 47));
r[25] ^= (uint8_t)((t.v[4] << 4) & 0xf0);
r[26] = (uint8_t)((t.v[4] >> 4) & 0xff);
r[27] = (uint8_t)((t.v[4] >> 12) & 0xff);
r[28] = (uint8_t)((t.v[4] >> 20) & 0xff);
r[29] = (uint8_t)((t.v[4] >> 28) & 0xff);
r[30] = (uint8_t)((t.v[4] >> 36) & 0xff);
r[31] = (uint8_t)((t.v[4] >> 44));
}
static void fe25519_unpack(fe25519 *r, const uint8_t x[32]) {
r->v[0] = x[0];
r->v[0] += (uint64_t)x[1] << 8;
r->v[0] += (uint64_t)x[2] << 16;
r->v[0] += (uint64_t)x[3] << 24;
r->v[0] += (uint64_t)x[4] << 32;
r->v[0] += (uint64_t)x[5] << 40;
r->v[0] += ((uint64_t)x[6] & 7) << 48;
r->v[1] = x[6] >> 3;
r->v[1] += (uint64_t)x[7] << 5;
r->v[1] += (uint64_t)x[8] << 13;
r->v[1] += (uint64_t)x[9] << 21;
r->v[1] += (uint64_t)x[10] << 29;
r->v[1] += (uint64_t)x[11] << 37;
r->v[1] += ((uint64_t)x[12] & 63) << 45;
r->v[2] = x[12] >> 6;
r->v[2] += (uint64_t)x[13] << 2;
r->v[2] += (uint64_t)x[14] << 10;
r->v[2] += (uint64_t)x[15] << 18;
r->v[2] += (uint64_t)x[16] << 26;
r->v[2] += (uint64_t)x[17] << 34;
r->v[2] += (uint64_t)x[18] << 42;
r->v[2] += ((uint64_t)x[19] & 1) << 50;
r->v[3] = x[19] >> 1;
r->v[3] += (uint64_t)x[20] << 7;
r->v[3] += (uint64_t)x[21] << 15;
r->v[3] += (uint64_t)x[22] << 23;
r->v[3] += (uint64_t)x[23] << 31;
r->v[3] += (uint64_t)x[24] << 39;
r->v[3] += ((uint64_t)x[25] & 15) << 47;
r->v[4] = x[25] >> 4;
r->v[4] += (uint64_t)x[26] << 4;
r->v[4] += (uint64_t)x[27] << 12;
r->v[4] += (uint64_t)x[28] << 20;
r->v[4] += (uint64_t)x[29] << 28;
r->v[4] += (uint64_t)x[30] << 36;
r->v[4] += ((uint64_t)x[31] & 127) << 44;
}
static void fe25519_invert(fe25519 *r, const fe25519 *x) {
fe25519 z2;
fe25519 z9;
fe25519 z11;
fe25519 z2_5_0;
fe25519 z2_10_0;
fe25519 z2_20_0;
fe25519 z2_50_0;
fe25519 z2_100_0;
fe25519 t;
int i;
/* 2 */ GFp_x25519_x86_64_square(&z2, x);
/* 4 */ GFp_x25519_x86_64_square(&t, &z2);
/* 8 */ GFp_x25519_x86_64_square(&t, &t);
/* 9 */ GFp_x25519_x86_64_mul(&z9, &t, x);
/* 11 */ GFp_x25519_x86_64_mul(&z11, &z9, &z2);
/* 22 */ GFp_x25519_x86_64_square(&t, &z11);
/* 2^5 - 2^0 = 31 */ GFp_x25519_x86_64_mul(&z2_5_0, &t, &z9);
/* 2^6 - 2^1 */ GFp_x25519_x86_64_square(&t, &z2_5_0);
/* 2^20 - 2^10 */ for (i = 1; i < 5; i++) { GFp_x25519_x86_64_square(&t, &t); }
/* 2^10 - 2^0 */ GFp_x25519_x86_64_mul(&z2_10_0, &t, &z2_5_0);
/* 2^11 - 2^1 */ GFp_x25519_x86_64_square(&t, &z2_10_0);
/* 2^20 - 2^10 */ for (i = 1; i < 10; i++) { GFp_x25519_x86_64_square(&t, &t); }
/* 2^20 - 2^0 */ GFp_x25519_x86_64_mul(&z2_20_0, &t, &z2_10_0);
/* 2^21 - 2^1 */ GFp_x25519_x86_64_square(&t, &z2_20_0);
/* 2^40 - 2^20 */ for (i = 1; i < 20; i++) { GFp_x25519_x86_64_square(&t, &t); }
/* 2^40 - 2^0 */ GFp_x25519_x86_64_mul(&t, &t, &z2_20_0);
/* 2^41 - 2^1 */ GFp_x25519_x86_64_square(&t, &t);
/* 2^50 - 2^10 */ for (i = 1; i < 10; i++) { GFp_x25519_x86_64_square(&t, &t); }
/* 2^50 - 2^0 */ GFp_x25519_x86_64_mul(&z2_50_0, &t, &z2_10_0);
/* 2^51 - 2^1 */ GFp_x25519_x86_64_square(&t, &z2_50_0);
/* 2^100 - 2^50 */ for (i = 1; i < 50; i++) { GFp_x25519_x86_64_square(&t, &t); }
/* 2^100 - 2^0 */ GFp_x25519_x86_64_mul(&z2_100_0, &t, &z2_50_0);
/* 2^101 - 2^1 */ GFp_x25519_x86_64_square(&t, &z2_100_0);
/* 2^200 - 2^100 */ for (i = 1; i < 100; i++) {
GFp_x25519_x86_64_square(&t, &t);
}
/* 2^200 - 2^0 */ GFp_x25519_x86_64_mul(&t, &t, &z2_100_0);
/* 2^201 - 2^1 */ GFp_x25519_x86_64_square(&t, &t);
/* 2^250 - 2^50 */ for (i = 1; i < 50; i++) { GFp_x25519_x86_64_square(&t, &t); }
/* 2^250 - 2^0 */ GFp_x25519_x86_64_mul(&t, &t, &z2_50_0);
/* 2^251 - 2^1 */ GFp_x25519_x86_64_square(&t, &t);
/* 2^252 - 2^2 */ GFp_x25519_x86_64_square(&t, &t);
/* 2^253 - 2^3 */ GFp_x25519_x86_64_square(&t, &t);
/* 2^254 - 2^4 */ GFp_x25519_x86_64_square(&t, &t);
/* 2^255 - 2^5 */ GFp_x25519_x86_64_square(&t, &t);
/* 2^255 - 21 */ GFp_x25519_x86_64_mul(r, &t, &z11);
}
static void mladder(fe25519 *xr, fe25519 *zr, const uint8_t s[32]) {
fe25519 work[5];
work[0] = *xr;
fe25519_setint(work + 1, 1);
fe25519_setint(work + 2, 0);
work[3] = *xr;
fe25519_setint(work + 4, 1);
int i, j;
uint8_t prevbit = 0;
j = 6;
for (i = 31; i >= 0; i--) {
while (j >= 0) {
const uint8_t bit = 1 & (s[i] >> j);
const uint64_t swap = bit ^ prevbit;
prevbit = bit;
GFp_x25519_x86_64_work_cswap(work + 1, swap);
GFp_x25519_x86_64_ladderstep(work);
j -= 1;
}
j = 7;
}
*xr = work[1];
*zr = work[2];
}
void GFp_x25519_x86_64(uint8_t out[32], const uint8_t scalar[32],
const uint8_t point[32]) {
uint8_t e[32];
memcpy(e, scalar, sizeof(e));
e[0] &= 248;
e[31] &= 127;
e[31] |= 64;
fe25519 t;
fe25519 z;
fe25519_unpack(&t, point);
mladder(&t, &z, e);
fe25519_invert(&z, &z);
GFp_x25519_x86_64_mul(&t, &t, &z);
fe25519_pack(out, &t);
}
#endif /* BORINGSSL_X25519_X86_64 */

View File

@@ -20,9 +20,13 @@ extra-source-files: CHANGELOG.md
executable gen-tests
main-is: Main.hs
other-modules: Database, DSA, ECDSATesting, Math, RFC6979, RSA, Task, Utils
other-modules: Database, DSA, ECDSATesting, ED25519, ED25519.PrecompPoints, Math, RFC6979, RSA, Task, Utils
-- other-extensions:
build-depends: base >=4.11 && < 4.14, ascii-progress, bytestring, containers, crypto-api, cryptonite, directory, DSA, filepath, integer-gmp, memory, random
hs-source-dirs: .
c-sources: cbits/curve25519.c cbits/x25519-x86_64.c cbits/x25519-asm-x86_64.S
include-dirs: cbits
default-language: Haskell2010
ghc-options: -Wall -O2 -threaded -rtsopts -with-rtsopts=-N
if os(Windows) || !arch(x86_64)
buildable: False

4004
testdata/ed25519/addsub.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/bytes.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/ed25519/cmov.test vendored Normal file

File diff suppressed because it is too large Load Diff

6006
testdata/ed25519/conversion.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/fbv.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/invert.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/ed25519/istests.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/ed25519/load.test vendored Normal file

File diff suppressed because it is too large Load Diff

4004
testdata/ed25519/maddsub.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/ed25519/mul.test vendored Normal file

File diff suppressed because it is too large Load Diff

4004
testdata/ed25519/muladd.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/negate.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/pow22523.test vendored Normal file

File diff suppressed because it is too large Load Diff

4004
testdata/ed25519/pt_double.test vendored Normal file

File diff suppressed because it is too large Load Diff

4004
testdata/ed25519/ptaddsub.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/pubfrompriv.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/reduce.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/scalar_mult.test vendored Normal file

File diff suppressed because it is too large Load Diff

4004
testdata/ed25519/scalar_mult_gen.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/slide.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/square.test vendored Normal file

File diff suppressed because it is too large Load Diff

2002
testdata/ed25519/square2.test vendored Normal file

File diff suppressed because it is too large Load Diff