#pragma once #include #include #include /* __device__ __constant__ unsigned char ed25519_order[32] = { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; */ __device__ __forceinline__ void expand_key(unsigned char* expanded, const unsigned char* secret) { struct sha512_state s; sha512_init(&s); sha512_final(&s, secret, 32); sha512_get(&s, expanded, 0, 64); ed25519_prepare(expanded); } /* __device__ __forceinline__ unsigned char upp(struct ed25519_pt* p, const unsigned char* packed) { unsigned char x[F25519_SIZE], y[F25519_SIZE]; unsigned char ok = ed25519_try_unpack(x, y, packed); ed25519_project(p, x, y); return ok; } */ __device__ __forceinline__ void pp(unsigned char* packed, const struct ed25519_pt* p) { unsigned char x[F25519_SIZE], y[F25519_SIZE]; ed25519_unproject(x, y, p); ed25519_pack(packed, x, y); } __device__ __forceinline__ void sm_pack(unsigned char* r, const unsigned char* k) { struct ed25519_pt p; ed25519_smult(&p, &ed25519_base, k); pp(r, &p); } __device__ __forceinline__ void edsign_sec_to_pub(unsigned char* pub, const unsigned char* secret) { unsigned char expanded[64]; expand_key(expanded, secret); sm_pack(pub, expanded); } /* __device__ __forceinline__ void hash_with_prefix(unsigned char* out_fp, unsigned char* init_block, unsigned int prefix_size, const unsigned char* message, unsigned long len) { struct sha512_state s; sha512_init(&s); if (len < 128 && len + prefix_size < 128) { memcpy(init_block + prefix_size, message, len); sha512_final(&s, init_block, len + prefix_size); } else { unsigned long i; memcpy(init_block + prefix_size, message, 128 - prefix_size); sha512_block(&s, init_block); for (i = 128 - prefix_size; i + 128 <= len; i += 128) { sha512_block(&s, message + i); } sha512_final(&s, message + i, len - i + prefix_size); } sha512_get(&s, init_block, 0, 64); fprime_from_bytes(out_fp, init_block, 64, ed25519_order); } __device__ __forceinline__ void generate_k(unsigned char* k, const unsigned char* kgen_key, const unsigned char* message, unsigned long len) { unsigned char block[128]; memcpy(block, kgen_key, 32); hash_with_prefix(k, block, 32, message, len); } __device__ __forceinline__ void hash_message(unsigned char* z, const unsigned char* r, const unsigned char* a, const unsigned char* m, unsigned long len) { unsigned char block[128]; memcpy(block, r, 32); memcpy(block + 32, a, 32); hash_with_prefix(z, block, 64, m, len); } __device__ void edsign_sign(unsigned char* signature, const unsigned char* pub, const unsigned char* secret, const unsigned char* message, unsigned long len) { unsigned char expanded[64]; unsigned char e[32], s[32], k[32], z[32]; expand_key(expanded, secret); generate_k(k, expanded + 32, message, len); sm_pack(signature, k); hash_message(z, signature, pub, message, len); fprime_from_bytes(e, expanded, 32, ed25519_order); fprime_mul(s, z, e, ed25519_order); fprime_add(s, k, ed25519_order); memcpy(signature + 32, s, 32); } __device__ unsigned char edsign_verify(const unsigned char* signature, const unsigned char* pub, const unsigned char* message, unsigned long len) { struct ed25519_pt p, q; unsigned char lhs[F25519_SIZE], rhs[F25519_SIZE], z[32]; unsigned char ok = 1; hash_message(z, signature, pub, message, len); sm_pack(lhs, signature + 32); ok &= upp(&p, pub); ed25519_smult(&p, &p, z); ok &= upp(&q, signature); ed25519_add(&p, &p, &q); pp(rhs, &p); return ok & f25519_eq(lhs, rhs); } */