public static void crypto_sign2( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] sk, int skoffset) { byte[] az = new byte[64]; byte[] r = new byte[64]; byte[] hram = new byte[64]; GroupElementP3 R; var hasher2 = new Sha3Digest(512); { hasher2.BlockUpdate(sk, 0, 32); hasher2.DoFinal(az, 0); ScalarOperations.sc_clamp(az, 0); hasher2.Reset(); hasher2.BlockUpdate(az, 32, 32); hasher2.BlockUpdate(m, moffset, mlen); hasher2.DoFinal(r, 0); ScalarOperations.sc_reduce(r); GroupOperations.ge_scalarmult_base(out R, r, 0); GroupOperations.ge_p3_tobytes(sig, sigoffset, ref R); hasher2.Reset(); hasher2.BlockUpdate(sig, sigoffset, 32); hasher2.BlockUpdate(sk, skoffset + 32, 32); hasher2.BlockUpdate(m, moffset, mlen); hasher2.DoFinal(hram, 0); ScalarOperations.sc_reduce(hram); var s = new byte[32]; Array.Copy(sig, sigoffset + 32, s, 0, 32); ScalarOperations.sc_muladd(s, hram, az, r); Array.Copy(s, 0, sig, sigoffset + 32, 32); CryptoBytes.Wipe(s); } }
public static bool crypto_sign_verify( byte[] sig, int sigoffset, byte[] m, int moffset, int mlen, byte[] pk, int pkoffset) { byte[] checkr = new byte[32]; GroupElementP3 A; GroupElementP2 R; if ((sig[sigoffset + 63] & 224) != 0) { return(false); } if (GroupOperations.ge_frombytes_negate_vartime(out A, pk, pkoffset) != 0) { return(false); } var hash = new Sha3Digest(512); hash.BlockUpdate(sig, sigoffset, 32); hash.BlockUpdate(pk, pkoffset, 32); hash.BlockUpdate(m, moffset, mlen); var b = new byte[64]; hash.DoFinal(b, 0); ScalarOperations.sc_reduce(b); var sm32 = new byte[32];//todo: remove allocation Array.Copy(sig, sigoffset + 32, sm32, 0, 32); GroupOperations.ge_double_scalarmult_vartime(out R, b, ref A, sm32); GroupOperations.ge_tobytes(checkr, 0, ref R); var result = CryptoBytes.ConstantTimeEquals(checkr, 0, sig, sigoffset, 32); CryptoBytes.Wipe(b); CryptoBytes.Wipe(checkr); return(result); }
internal static void crypto_sign_keypair(byte[] pk, int pkoffset, byte[] sk, int skoffset, byte[] seed, int seedoffset) { GroupElementP3 A; int i; Array.Copy(seed, seedoffset, sk, skoffset, 32); var digest = new Sha3Digest(512); //new // tried and failed -> new Sha3Digest(512); var h = new byte[64]; // byte[] ha = Sha512.Hash(sk, skoffset, 32);//ToDo: REMOVE alloc digest.BlockUpdate(sk, skoffset, 32); // new digest.DoFinal(h, 0); // new ScalarOperations.sc_clamp(h, 0); GroupOperations.ge_scalarmult_base(out A, h, 0); GroupOperations.ge_p3_tobytes(pk, pkoffset, ref A); for (i = 0; i < 32; ++i) { sk[skoffset + 32 + i] = pk[pkoffset + i]; } CryptoBytes.Wipe(h); }