Skip to content

Commit e6ac8f1

Browse files
nicole-grausNicole
andauthored
Add secq256k1 Curve (lambdaclass#915)
* create secq256k1 curve * save work. tests working * change READMEs * fix typo * fix README --------- Co-authored-by: Nicole <nicole@Nicoles-MacBook-Air.local>
1 parent aeaa979 commit e6ac8f1

File tree

6 files changed

+174
-2
lines changed

6 files changed

+174
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ List of symbols:
9595
| Vesta | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | :heavy_check_mark: |
9696
| Bandersnatch | 🏗️ | :heavy_check_mark: | :x: | :heavy_check_mark: | :heavy_check_mark: |
9797
| secp256k1 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
98+
| secq256k1 | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :x: | :x: |
9899
| **STARKs** | **Lambdaworks** | **Arkworks** | **Halo2** | **gnark** | **Constantine** |
99100
| STARK Prover | :heavy_check_mark: | :x: | :x: | :x: | :x: |
100101
| CAIRO Prover | 🏗️ | :x: | :x: | :x: | :x: |

math/src/elliptic_curve/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ The following curves are currently supported:
2020
- [Vesta](https://github.com/lambdaclass/lambdaworks/tree/main/math/src/elliptic_curve/short_weierstrass/curves/vesta), useful for recursive SNARKs when used with Pallas.
2121
- [Starknet's curve](https://github.com/lambdaclass/lambdaworks/blob/main/math/src/elliptic_curve/short_weierstrass/curves/stark_curve.rs)
2222
- [secp256k1](./short_weierstrass/curves/secp256k1/curve.rs): Bitcoin's curve. The implementation is not constant time, so it cannot be used to sign messages!
23+
- [secq256k1](./short_weierstrass/curves/secq256k1/curve.rs): It has the same curve equation as secp256k1, a different generator and their order r and the modulus p are swapped. It uses ```secp256k1_scalarfield``` as a base field, which has modulus r.
2324

2425
## Twisted Edwards
2526

math/src/elliptic_curve/short_weierstrass/curves/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod bn_254;
44
pub mod grumpkin;
55
pub mod pallas;
66
pub mod secp256k1;
7+
pub mod secq256k1;
78
pub mod stark_curve;
89
pub mod test_curve_1;
910
pub mod test_curve_2;

math/src/elliptic_curve/short_weierstrass/curves/secp256k1/curve.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,8 @@ mod tests {
123123
let y = g2_affine.y();
124124

125125
// calculate both sides of secp256k1 curve equation
126-
let five = Secp256k1Curve::b();
127-
let y_sq_0 = x.pow(3_u16) + five;
126+
let seven = Secp256k1Curve::b();
127+
let y_sq_0 = x.pow(3_u16) + seven;
128128
let y_sq_1 = y.pow(2_u16);
129129

130130
assert_eq!(y_sq_0, y_sq_1);
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
use crate::elliptic_curve::short_weierstrass::point::ShortWeierstrassProjectivePoint;
2+
use crate::elliptic_curve::traits::IsEllipticCurve;
3+
use crate::field::fields::secp256k1_scalarfield::Secp256k1ScalarField;
4+
use crate::{
5+
elliptic_curve::short_weierstrass::traits::IsShortWeierstrass, field::element::FieldElement,
6+
};
7+
8+
#[derive(Clone, Debug)]
9+
pub struct Secq256k1Curve;
10+
11+
impl IsEllipticCurve for Secq256k1Curve {
12+
type BaseField = Secp256k1ScalarField;
13+
type PointRepresentation = ShortWeierstrassProjectivePoint<Self>;
14+
15+
fn generator() -> Self::PointRepresentation {
16+
Self::PointRepresentation::new([
17+
FieldElement::<Self::BaseField>::from_hex_unchecked(
18+
"76C39F5585CB160EB6B06C87A2CE32E23134E45A097781A6A24288E37702EDA6",
19+
),
20+
FieldElement::<Self::BaseField>::from_hex_unchecked(
21+
"3FFC646C7B2918B5DC2D265A8E82A7F7D18983D26E8DC055A4120DDAD952677F",
22+
),
23+
FieldElement::one(),
24+
])
25+
}
26+
}
27+
28+
impl IsShortWeierstrass for Secq256k1Curve {
29+
fn a() -> FieldElement<Self::BaseField> {
30+
FieldElement::from(0)
31+
}
32+
33+
fn b() -> FieldElement<Self::BaseField> {
34+
FieldElement::from(7)
35+
}
36+
}
37+
38+
#[cfg(test)]
39+
mod tests {
40+
use super::*;
41+
use crate::{
42+
cyclic_group::IsGroup, elliptic_curve::traits::EllipticCurveError,
43+
field::element::FieldElement, unsigned_integer::element::U256,
44+
};
45+
46+
use super::Secq256k1Curve;
47+
48+
#[allow(clippy::upper_case_acronyms)]
49+
type FE = FieldElement<Secp256k1ScalarField>;
50+
51+
fn point_1() -> ShortWeierstrassProjectivePoint<Secq256k1Curve> {
52+
let x = FE::from_hex_unchecked(
53+
"76C39F5585CB160EB6B06C87A2CE32E23134E45A097781A6A24288E37702EDA6",
54+
);
55+
let y = FE::from_hex_unchecked(
56+
"3FFC646C7B2918B5DC2D265A8E82A7F7D18983D26E8DC055A4120DDAD952677F",
57+
);
58+
Secq256k1Curve::create_point_from_affine(x, y).unwrap()
59+
}
60+
61+
fn point_1_times_5() -> ShortWeierstrassProjectivePoint<Secq256k1Curve> {
62+
let x = FE::from_hex_unchecked(
63+
"8656a2c13dd0a3bfa362d2ff8c00281341ff3a79cbbe8857f2d20b398041a21a",
64+
);
65+
let y = FE::from_hex_unchecked(
66+
"468ed8bcfcd4ed2b3bf154414b9e48d8c5ce54f6616846a7cf6a725f70d34a63",
67+
);
68+
let z = FE::from_hex_unchecked(
69+
"bb26eae3d2b9603d98dff86d87175f442e539c07bbe4ef5712e47c4d72c89734",
70+
);
71+
ShortWeierstrassProjectivePoint::<Secq256k1Curve>::new([x, y, z])
72+
}
73+
74+
#[test]
75+
fn adding_five_times_point_1_works() {
76+
let point_1 = point_1();
77+
let point_1_times_5 = point_1_times_5();
78+
assert_eq!(point_1.operate_with_self(5_u16), point_1_times_5);
79+
}
80+
81+
#[test]
82+
fn create_valid_point_works() {
83+
let p = point_1();
84+
assert_eq!(
85+
*p.x(),
86+
FE::from_hex_unchecked(
87+
"76C39F5585CB160EB6B06C87A2CE32E23134E45A097781A6A24288E37702EDA6"
88+
)
89+
);
90+
assert_eq!(
91+
*p.y(),
92+
FE::from_hex_unchecked(
93+
"3FFC646C7B2918B5DC2D265A8E82A7F7D18983D26E8DC055A4120DDAD952677F"
94+
)
95+
);
96+
assert_eq!(*p.z(), FE::from_hex_unchecked("1"));
97+
}
98+
99+
#[test]
100+
fn create_invalid_points_returns_an_error() {
101+
assert_eq!(
102+
Secq256k1Curve::create_point_from_affine(FE::from(0), FE::from(1)),
103+
Err(EllipticCurveError::InvalidPoint)
104+
);
105+
}
106+
107+
#[test]
108+
fn equality_works() {
109+
let g = Secq256k1Curve::generator();
110+
let g2 = g.operate_with_self(2_u16);
111+
let g2_other = g.operate_with(&g);
112+
assert_ne!(&g2, &g);
113+
assert_eq!(&g, &g);
114+
assert_eq!(&g2, &g2_other);
115+
}
116+
117+
#[test]
118+
fn g_operated_with_g_satifies_ec_equation() {
119+
let g = Secq256k1Curve::generator();
120+
let g2 = g.operate_with_self(2_u16);
121+
122+
// get x and y from affine coordinates
123+
let g2_affine = g2.to_affine();
124+
let x = g2_affine.x();
125+
let y = g2_affine.y();
126+
127+
// calculate both sides of secq256k1 curve equation
128+
let seven = Secq256k1Curve::b();
129+
let y_sq_0 = x.pow(3_u16) + seven;
130+
let y_sq_1 = y.pow(2_u16);
131+
132+
assert_eq!(y_sq_0, y_sq_1);
133+
}
134+
135+
#[test]
136+
fn operate_with_self_works() {
137+
let g = Secq256k1Curve::generator();
138+
assert_eq!(
139+
g.operate_with(&g).operate_with(&g),
140+
g.operate_with_self(3_u16)
141+
);
142+
}
143+
144+
#[test]
145+
fn generator_has_right_order() {
146+
let g = Secq256k1Curve::generator();
147+
assert_eq!(
148+
g.operate_with_self(U256::from_hex_unchecked(
149+
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"
150+
))
151+
.to_affine(),
152+
ShortWeierstrassProjectivePoint::neutral_element()
153+
);
154+
}
155+
156+
#[test]
157+
/// (r - 5)g = rg - 5g = 0 - 5g = -5g
158+
fn inverse_works() {
159+
let g = Secq256k1Curve::generator();
160+
assert_eq!(
161+
g.operate_with_self(U256::from_hex_unchecked(
162+
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2A"
163+
))
164+
.to_affine(),
165+
g.operate_with_self(5u64).neg().to_affine()
166+
);
167+
}
168+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod curve;

0 commit comments

Comments
 (0)