Skip to content

Commit 596113e

Browse files
committed
bignp256: migrate to LittleEndian, according to specification
1 parent 29f0a68 commit 596113e

File tree

14 files changed

+191
-166
lines changed

14 files changed

+191
-166
lines changed

Cargo.lock

Lines changed: 22 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bignp256/Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,22 @@ rust-version = "1.85"
2121
elliptic-curve = { version = "0.14.0-rc.29", features = ["sec1"] }
2222

2323
# optional dependencies
24+
belt-block = { version = "0.2.0-rc.3", optional = true}
2425
belt-hash = { version = "0.2.0-rc.5", optional = true, default-features = false }
2526
der = "0.8"
2627
digest = { version = "0.11", optional = true }
2728
hex-literal = { version = "1", optional = true }
2829
hkdf = { version = "0.13.0-rc.5", optional = true }
2930
hmac = { version = "0.13.0-rc.5", optional = true }
3031
rand_core = "0.10"
31-
rfc6979 = { version = "0.5.0-rc.5", optional = true }
3232
pkcs8 = { version = "0.11.0-rc.11", optional = true }
3333
primefield = { version = "0.14.0-rc.8", optional = true }
3434
primeorder = { version = "0.14.0-rc.8", optional = true }
3535
sec1 = { version = "0.8.0-rc.13", optional = true }
3636
signature = { version = "3.0.0-rc.10", optional = true }
37+
# TODO: Change this when `bign-genk` is released
38+
bign-genk = { git = "https://github.com/makavity/signatures.git", optional = true }
39+
#bign-genk = { path = "../../signatures/bign-genk", optional = true }
3740

3841
[dev-dependencies]
3942
criterion = "0.7"
@@ -49,7 +52,7 @@ std = ["alloc", "elliptic-curve/std", "getrandom"]
4952

5053
arithmetic = ["dep:primefield", "dep:primeorder", "elliptic-curve/arithmetic"]
5154
bits = ["arithmetic", "elliptic-curve/bits"]
52-
ecdsa = ["arithmetic", "dep:rfc6979", "dep:signature", "dep:belt-hash"]
55+
ecdsa = ["arithmetic", "dep:signature", "dep:belt-hash", "dep:bign-genk", "dep:belt-block", "belt-block/cipher", "belt-hash/oid"]
5356
getrandom = ["elliptic-curve/getrandom"]
5457
pem = ["pkcs8/pem", "sec1/pem"]
5558
pkcs8 = ["dep:pkcs8"]

bignp256/src/arithmetic.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ impl PrimeCurveParams for BignP256 {
3535
type FieldElement = FieldElement;
3636
type PointArithmetic = point_arithmetic::EquationAIsGeneric;
3737
const EQUATION_A: Self::FieldElement = FieldElement::from_hex_vartime(
38-
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40",
38+
"40FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
3939
);
4040
const EQUATION_B: Self::FieldElement = FieldElement::from_hex_vartime(
41-
"77CE6C1515F3A8EDD2C13AABE4D8FBBE4CF55069978B9253B22E7D6BD69C03F1",
41+
"F1039CD66B7D2EB253928B976950F54CBEFBD8E4AB3AC1D2EDA8F315156CCE77",
4242
);
4343
const GENERATOR: (Self::FieldElement, Self::FieldElement) = (
4444
FieldElement::ZERO,
4545
FieldElement::from_hex_vartime(
46-
"6BF7FC3CFB16D69F5CE4C9A351D6835D78913966C408F6521E29CF1804516A93",
46+
"936A510418CF291E52F608C4663991785D83D651A3C9E45C9FD616FB3CFCF76B",
4747
),
4848
);
4949
}

bignp256/src/arithmetic/field.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ primefield::monty_field_params! {
6161
name: FieldParams,
6262
modulus: MODULUS_HEX,
6363
uint: U256,
64-
byte_order: primefield::ByteOrder::BigEndian,
64+
byte_order: primefield::ByteOrder::LittleEndian,
6565
multiplicative_generator: 2,
6666
doc: "Montgomery parameters for the bign-curve256v1 field modulus p = 2^{256} − 189"
6767
}

bignp256/src/arithmetic/scalar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ primefield::monty_field_params! {
5252
name: ScalarParams,
5353
modulus: ORDER_HEX,
5454
uint: U256,
55-
byte_order: primefield::ByteOrder::BigEndian,
55+
byte_order: primefield::ByteOrder::LittleEndian,
5656
multiplicative_generator: 3,
5757
doc: "Montgomery parameters for the bign-curve256v1 scalar modulus"
5858
}

bignp256/src/ecdsa.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ impl Signature {
7575
/// Parse an BignP256 signature from a byte array.
7676
pub fn from_bytes(bytes: &SignatureBytes) -> Result<Self> {
7777
let (s0, s1) = bytes.split_at(Self::BYTE_SIZE / 3);
78+
7879
let mut s0_bytes: Array<u8, U32> = Default::default();
7980
s0_bytes[..16].copy_from_slice(s0);
8081

@@ -99,11 +100,8 @@ impl Signature {
99100
/// which comprise the signature.
100101
#[inline]
101102
pub fn from_scalars(s0: impl Into<FieldBytes>, s1: impl Into<FieldBytes>) -> Result<Self> {
102-
let s0 = &mut s0.into()[16..];
103-
let mut s1 = s1.into();
104-
105-
s0.reverse();
106-
s1.reverse();
103+
let s0 = &mut s0.into()[..16];
104+
let s1 = s1.into();
107105

108106
let mut s: Array<u8, U48> = Default::default();
109107
s[..Self::BYTE_SIZE / 3].copy_from_slice(s0);
@@ -142,15 +140,13 @@ impl Signature {
142140
impl Signature {
143141
/// Get the `s0` word component of this signature
144142
pub fn s0(&self) -> NonZeroScalar {
145-
let mut s0 = self.s0.to_bytes();
146-
s0.reverse();
143+
let s0 = self.s0.to_bytes();
147144
NonZeroScalar::new(Scalar::from_bytes(&s0).unwrap()).unwrap()
148145
}
149146

150147
/// Get the `s1` word component of this signature
151148
pub fn s1(&self) -> NonZeroScalar {
152-
let mut s1 = self.s1.to_bytes();
153-
s1.reverse();
149+
let s1 = self.s1.to_bytes();
154150
NonZeroScalar::new(Scalar::from_bytes(&s1).unwrap()).unwrap()
155151
}
156152

bignp256/src/ecdsa/signing.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{BignP256, FieldBytes, NonZeroScalar, ProjectivePoint, PublicKey, Sca
1919
use belt_hash::{BeltHash, Digest};
2020
use core::fmt::{self, Debug};
2121
use elliptic_curve::{
22-
Curve, Field, FieldBytesEncoding, Generate, Group, PrimeField,
22+
Curve, Field, FieldBytesEncoding, Generate, Group,
2323
array::{Array, sizes::U32, typenum::Unsigned},
2424
ops::Reduce,
2525
point::AffineCoordinates,
@@ -109,39 +109,38 @@ impl PrehashSigner<Signature> for SigningKey {
109109
if prehash.len() != <BignP256 as Curve>::FieldBytesSize::USIZE {
110110
return Err(Error::new());
111111
}
112-
let mut h_word: Array<u8, U32> = Array::try_from(prehash).map_err(|_| Error::new())?;
113-
h_word.reverse();
112+
let h_word: Array<u8, U32> = Array::try_from(prehash).map_err(|_| Error::new())?;
114113

115114
let h = Scalar::reduce(&h_word);
116115

117-
//2. Generate 𝑘 ← rand(1,..,𝑞-1)
118-
let k = Scalar::from_repr(rfc6979::generate_k::<BeltHash, _>(
119-
&self.secret_scalar.to_repr(),
116+
// //2. Generate 𝑘 ← rand(1,..,𝑞-1)
117+
let k = bign_genk::generate_k::<BeltHash, belt_block::BeltBlock, _>(
118+
&self.secret_scalar.to_bytes(),
120119
&FieldBytesEncoding::<BignP256>::encode_field_bytes(BignP256::ORDER.as_ref()),
121120
&h.to_bytes(),
122121
&[],
123-
))
124-
.unwrap();
122+
);
123+
124+
let k = Scalar::from_bytes(&k).unwrap();
125125

126126
// 3. Set 𝑅 ← 𝑘𝐺.
127-
let mut R: Array<u8, _> = ProjectivePoint::mul_by_generator(&k).to_affine().x();
128-
R.reverse();
127+
let R = ProjectivePoint::mul_by_generator(&k).to_affine();
128+
let Rx = R.x();
129129

130130
// 4. Set 𝑆0 ← ⟨︀belt-hash(OID(ℎ) ‖ ⟨𝑅⟩2𝑙 ‖ 𝐻)⟩︀_𝑙.
131131
let mut hasher = BeltHash::new();
132132
hasher.update(BELT_OID);
133-
hasher.update(R);
133+
hasher.update(Rx);
134134
hasher.update(prehash);
135135

136136
let mut s0 = hasher.finalize();
137137
s0[16..].fill(0x00);
138-
s0.reverse();
139138

140139
let s0_scalar = Scalar::from_slice(&s0).ok_or_else(Error::new)?;
141140

142141
let right = s0_scalar
143142
.add(&Scalar::from_u64(2).pow([128, 0, 0, 0]))
144-
.multiply(self.as_nonzero_scalar());
143+
.multiply(&self.secret_scalar);
145144

146145
// 5. Set 𝑆1 ← ⟨︀(𝑘 − 𝐻 − (𝑆0 + 2^𝑙)𝑑) mod 𝑞⟩︀_2𝑙.
147146
let s1 = k.sub(&h).sub(&right);

bignp256/src/ecdsa/verifying.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,12 @@ use belt_hash::{
2828
use elliptic_curve::{
2929
Curve, Field, Group,
3030
array::{Array, sizes::U32, typenum::Unsigned},
31-
group::GroupEncoding,
3231
ops::{LinearCombination, Reduce},
32+
point::AffineCoordinates,
33+
sec1::ToSec1Point,
3334
};
3435
use signature::{Error, MultipartVerifier, Result, Verifier, hazmat::PrehashVerifier};
3536

36-
use elliptic_curve::sec1::ToSec1Point;
37-
3837
/// Bign256 public key used for verifying signatures are valid for a given
3938
/// message.
4039
///
@@ -114,8 +113,7 @@ impl PrehashVerifier<Signature> for VerifyingKey {
114113
// 3. If 𝑆1 ⩾ 𝑞, return NO.
115114
let s1 = signature.s1();
116115

117-
let mut hash: Array<u8, U32> = Array::clone_from_slice(prehash);
118-
hash.reverse();
116+
let hash: Array<u8, U32> = Array::clone_from_slice(prehash);
119117

120118
let hw = Scalar::reduce(FieldBytes::from_slice(&hash));
121119
let left = s1.add(&hw);
@@ -133,19 +131,18 @@ impl PrehashVerifier<Signature> for VerifyingKey {
133131
return Err(Error::new());
134132
}
135133

136-
let mut r_bytes = r.to_bytes();
137-
r_bytes.reverse();
134+
let r = r.to_affine();
135+
let rx = r.x();
138136

139137
let mut hasher = BeltHash::new();
140138
hasher.update(BELT_OID);
141-
hasher.update(&r_bytes[0..32]);
139+
hasher.update(rx);
142140
hasher.update(prehash);
143141

144142
// 7. Set 𝑡 ← ⟨︀belt-hash(OID(ℎ) ‖ ⟨𝑅⟩^2𝑙 ‖ 𝐻) ⟩︀^𝑙.
145143
let t = hasher.finalize();
146144

147-
let s0 = &mut s0.to_bytes()[16..];
148-
s0.reverse();
145+
let s0 = &mut s0.to_bytes()[..16];
149146

150147
// 8. If 𝑆0 != 𝑡, return NO.
151148
if s0 == &t.as_slice()[..16] {

bignp256/src/lib.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,22 +128,18 @@ pub type Sec1Point = elliptic_curve::sec1::Sec1Point<BignP256>;
128128

129129
impl FieldBytesEncoding<BignP256> for U256 {
130130
fn decode_field_bytes(field_bytes: &FieldBytes) -> Self {
131-
U256::from_be_byte_array(*field_bytes)
131+
U256::from_le_byte_array(*field_bytes)
132132
}
133133

134134
fn encode_field_bytes(&self) -> FieldBytes {
135-
self.to_be_byte_array()
135+
self.to_le_byte_array()
136136
}
137137
}
138138

139139
/// Non-zero scalar field element.
140140
#[cfg(feature = "arithmetic")]
141141
pub type NonZeroScalar = elliptic_curve::NonZeroScalar<BignP256>;
142142

143-
// /// BIGN P-256 public key.
144-
// #[cfg(feature = "arithmetic")]
145-
// pub type PublicKey = elliptic_curve::PublicKey<BignP256>;
146-
147143
/// Generic scalar type with primitive functionality.#
148144
#[cfg(feature = "arithmetic")]
149145
pub type ScalarValue = elliptic_curve::ScalarValue<BignP256>;

bignp256/src/public_key.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,7 @@ impl PublicKey {
6464

6565
/// Get [`PublicKey`] from bytes
6666
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
67-
let mut bytes = Array::try_from(bytes).map_err(|_| Error)?;
68-
69-
// It is because public_key in little endian
70-
bytes[..32].reverse();
71-
bytes[32..].reverse();
67+
let bytes = Array::try_from(bytes).map_err(|_| Error)?;
7268

7369
let point = Sec1Point::from_untagged_bytes(&bytes);
7470
let affine = AffinePoint::from_sec1_point(&point);
@@ -96,9 +92,7 @@ impl PublicKey {
9692
#[cfg(feature = "alloc")]
9793
/// Get bytes from [`PublicKey`]
9894
pub fn to_bytes(&self) -> Box<[u8]> {
99-
let mut bytes = self.point.to_sec1_point(false).to_bytes();
100-
bytes[1..32 + 1].reverse();
101-
bytes[33..].reverse();
95+
let bytes = self.point.to_sec1_point(false).to_bytes();
10296
bytes[1..].to_vec().into_boxed_slice()
10397
}
10498

0 commit comments

Comments
 (0)