-
Notifications
You must be signed in to change notification settings - Fork 0
/
signature.rs
119 lines (99 loc) · 3.46 KB
/
signature.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#![allow(non_snake_case)]
#![allow(dead_code)]
#![allow(non_upper_case_globals)]
#![allow(unused_imports)]
// Elliptic curve based digital signature template
// See for example https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
// uncomment one or the other
/*
mod weierstrass;
use weierstrass::*;
use weierstrass::ECP;
*/
/*
mod edwards;
use edwards::*;
use edwards::ECP;
*/
mod hash;
use hash::*;
//use hash::SHA256; // choose your hash function here
/*** Insert code automatically generated in group.rs here ***/
/* Note that much of this code is not needed and can be deleted */
/*** End of automatically generated code ***/
const LIMBS:usize= NLIMBS;
type GEL = [SPINT; LIMBS];
const BYTES:usize = NBYTES;
// Some utility functions for I/O and debugging
fn char2int(inp: u8) -> u8 {
if inp>='0' as u8 && inp <='9' as u8 {
return inp-'0' as u8;
}
if inp>='A' as u8 && inp <='F' as u8 {
return inp-('A' as u8) +10;
}
if inp>='a' as u8 && inp <='f' as u8 {
return inp-('a' as u8) +10;
}
return 0;
}
// string s better have even number of characters!
fn from_hex(ilen:usize,s: &str,x: &mut[u8]) {
let mut pad:[u8;128]=[0;128];
let c=s.as_bytes();
let len=c.len();
let mut lz=2*ilen-len;
if 2*ilen<len {lz=0;}
for i in 0..lz {
pad[i]='0' as u8;
}
for i in lz..2*ilen {
pad[i]=c[i-lz];
}
for i in 0..ilen {
x[i]=char2int(pad[2*i])*16+char2int(pad[2*i+1]);
}
}
fn printhex(len:usize,array: &[u8]) {
for i in 0..len {
print!("{:02X}", array[i])
}
println!("")
}
// API implementation
// Input private key
// Output public key
pub fn XXX_KEY_GEN(prv: &[u8],public: &mut [u8]) {
let mut P=ECP::new();
ecngen(&mut P); // get curve generator point
// Scheme specific code
}
// Note that a per message "random" number usually generated by a Cryptographically Secure Random Number Generator (CSRNG) is often required, and if so is calculated externally and passed into the signature function
// Methods are
// 1. non-deterministic - a non-biased high entropy random number in the range from 0 - q (the group order) - recommended if CSRNG is good
// 2. deterministic - derived from a hash of the message to be signed and the secret key (must be done like this for EdDSA, optional for ECDSA)
// 3. hedged - a combination of methods 1 and 2 - recommended if CSRNG is poor
// Note that this functionality is out-of-scope for this exercise (except for EdDSA). For examples see https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf and RFC6979
// To create such a per message random number, consider the method reduce() from Ed448.rs, which reduces a much larger number modulo q, as required to minimize bias
// input private key, per-message random number (or public key), message to be signed
// Output signature.
pub fn XXX_SIGN(prv: &[u8],rp: &[u8],m:&[u8],sig: &mut [u8]) {
let mut P=ECP::new();
ecngen(&mut P); // get curve generator point
let mut r:GEL = [0;LIMBS]; // some group elements..
let mut s:GEL = [0;LIMBS];
// Scheme specific code
}
// input public key, message and signature.
// Return true for success, false for failure
pub fn XXX_VERIFY(public: &[u8],m:&[u8],sig:&[u8]) -> bool {
let mut P=ECP::new();
ecngen(&mut P); // get curve generator point
let mut r:GEL = [0;LIMBS]; // some group elements..
let mut s:GEL = [0;LIMBS];
// Scheme specific code
}
// Test vectors
fn main() {
// Implement some test vectors here
}