Skip to content

Commit 899f19c

Browse files
authored
feat: Commit (#61)
* wip: scalar mult wrangling * bug: tests run forever * merge in changes * chore: commitment is type at infinity * feat: more tests and sanity checks
1 parent ac1ffbb commit 899f19c

5 files changed

Lines changed: 105 additions & 32 deletions

File tree

math/curve.sage

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,16 @@ g1SRS = [(2**i)*G1 for i in range(7)]
5858
print(g1SRS)
5959

6060
g2SRS = [(2**i)*G2 for i in range(2)]
61-
print(g2SRS)
61+
print(g2SRS)
62+
63+
64+
######################################################################
65+
GF17 = GF(17)
66+
67+
coefs = [11, 11, 11, 1]
68+
# 11 * g1_srs[0] + 11 * g1_srs[1] + 11 * g1_srs[2] + 1 * g1_srs[3]
69+
muls = [(coefs[i] * g1SRS[i]) for i in range(4)]
70+
commitment = sum(muls)
71+
print(commitment)
72+
73+

src/curves/mod.rs

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,7 @@ pub enum AffinePoint<C: EllipticCurve> {
4040

4141
impl<C: EllipticCurve> AffinePoint<C> {
4242
/// Create a new point on the curve so long as it satisfies the curve equation.
43-
///
44-
/// ## Panics
45-
/// If the point is not on the curve; validated by checking if `y^2 = x^3 + ax + b`.
4643
pub fn new(x: C::BaseField, y: C::BaseField) -> Self {
47-
// okay so this is breaking because the curve equation doesn't know how to plug in polynomials.
48-
// y = 31x -> y^2 = 52x^2
49-
// x = 36 -> x^3 = 95 + 3
50-
// 52x^2 = 98 ???
5144
assert_eq!(
5245
y * y,
5346
x * x * x + C::EQUATION_A.into() * x + C::EQUATION_B.into(),
@@ -74,22 +67,18 @@ impl<C: EllipticCurve> Neg for AffinePoint<C> {
7467

7568
// TODO: This should likely use a `Self::ScalarField` instead of `u32`.
7669
/// Scalar multiplication on the rhs: P*(u32)
70+
/// This is the niave implementation of scalar multiplication
71+
/// There is a faster way to do this but this is simpler to reason about for now
72+
#[allow(clippy::suspicious_arithmetic_impl)]
7773
impl<C: EllipticCurve> Mul<u32> for AffinePoint<C> {
7874
type Output = AffinePoint<C>;
7975

80-
fn mul(self, scalar: u32) -> Self::Output {
81-
let mut result = AffinePoint::Infinity;
82-
let mut base = self;
83-
let mut exp = scalar;
84-
85-
while exp > 0 {
86-
if exp % 2 == 1 {
87-
result = result + base;
88-
}
89-
base = base.point_doubling();
90-
exp /= 2;
76+
fn mul(mut self, scalar: u32) -> Self::Output {
77+
let val = self;
78+
for _ in 1..scalar {
79+
self = self + val;
9180
}
92-
result
81+
self
9382
}
9483
}
9584

@@ -157,7 +146,7 @@ impl<C: EllipticCurve> AffinePoint<C> {
157146
AffinePoint::PointOnCurve(x, y) => (x, y),
158147
AffinePoint::Infinity => panic!("Cannot double point at infinity"),
159148
};
160-
// m = (3x^2) / (2y)
149+
// m = (3x^2) + a / (2y) (a = 0 on our curve)
161150
let m = ((C::BaseField::TWO + C::BaseField::ONE) * x * x) / (C::BaseField::TWO * y);
162151

163152
// 2P = (m^2 - 2x, m(3x - m^2)- y)

src/field/gf_101.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub const PLUTO_FIELD_PRIME: u32 = 101;
1010

1111
/// [`GF101`] represents the finite field GF(101) that has 101 elements and works with typical sum
1212
/// and multiplication operations modulo 101.
13-
#[derive(Copy, Clone, Default, Debug, Hash, PartialEq, Eq)]
13+
#[derive(Copy, Clone, Default, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
1414
pub struct GF101 {
1515
value: u32,
1616
}

src/field/mod.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub trait FiniteField:
2020
+ Clone
2121
+ PartialEq
2222
+ Eq
23+
+ PartialOrd
2324
+ Add<Output = Self>
2425
+ AddAssign
2526
+ Sum
@@ -122,7 +123,7 @@ where [B; N + 1]: {
122123
/// A struct that represents an element of an extension field. The element is represented as
123124
/// [`Monomial`] coefficients of a [`Polynomial`] of degree `N - 1` over the base [`FiniteField`]
124125
/// `F`.
125-
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
126+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug, PartialOrd)]
126127
pub struct Ext<const N: usize, F: FiniteField> {
127128
pub(crate) coeffs: [F; N],
128129
}
@@ -297,19 +298,36 @@ pub fn get_generator(p: u32) -> i32 {
297298
}
298299
-1
299300
}
300-
301-
fn powmod(base: u32, exponent: u32, modulus: u32) -> u32 {
302-
let mut base = base as u64;
301+
//
302+
/// Computes the power of a base raised to an exponent under modulo using the method of
303+
/// Exponentiation by Squaring.
304+
///
305+
/// This method is used for its efficiency in calculating large powers of a number in modular
306+
/// arithmetic, which is a common operation in many cryptographic algorithms. It reduces the number
307+
/// of multiplications needed by squaring the base and halving the exponent in each step, thus
308+
/// operating in O(log exponent) time.
309+
///
310+
/// # Arguments
311+
/// * `base` - The base number as a `u32`.
312+
/// * `exponent` - The exponent as a `u32`.
313+
/// * `modulus` - The modulus as a `u32`.
314+
///
315+
/// # Returns
316+
/// * The result of (base^exponent) % modulus as a `u32`.
317+
pub fn powmod(base: u32, exponent: u32, modulus: u32) -> u32 {
318+
let mut base = base as u64; // Use u64 to prevent overflow during calculations
303319
let mut exponent = exponent;
304320
let modulus = modulus as u64;
305-
let mut result = 1;
306-
base %= modulus;
321+
let mut result = 1; // Start with the multiplicative identity
322+
base %= modulus; // Reduce base modulo initially to simplify further calculations
323+
307324
while exponent > 0 {
308325
if exponent % 2 == 1 {
326+
// If the exponent is odd, multiply the current result by the base
309327
result = (result * base) % modulus;
310328
}
311-
base = (base * base) % modulus;
312-
exponent >>= 1;
329+
base = (base * base) % modulus; // Square the base
330+
exponent >>= 1; // Divide the exponent by 2
313331
}
314-
result as u32
332+
result as u32 // Return the result as u32
315333
}

src/setup.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
33
use super::*;
44

5+
/// simple setup to get params.
56
#[allow(dead_code, clippy::type_complexity)]
6-
fn setup() -> (Vec<AffinePoint<PlutoCurve<GF101>>>, Vec<AffinePoint<PlutoCurve<Ext<2, GF101>>>>) {
7+
pub fn setup() -> (Vec<AffinePoint<PlutoCurve<GF101>>>, Vec<AffinePoint<PlutoCurve<Ext<2, GF101>>>>)
8+
{
79
// NOTE: For demonstration purposes only.
810

911
// This is just tau from plonk by hand, it is not actually secure
@@ -33,6 +35,28 @@ fn setup() -> (Vec<AffinePoint<PlutoCurve<GF101>>>, Vec<AffinePoint<PlutoCurve<E
3335
(srs_g1_points, srs_g2_points)
3436
}
3537

38+
/// kzg poly commit
39+
#[allow(dead_code)]
40+
fn commit(
41+
coefs: Vec<u32>,
42+
g1_srs: Vec<AffinePoint<PlutoCurve<GF101>>>,
43+
) -> AffinePoint<PlutoCurve<GF101>> {
44+
// commit to a polynomial
45+
// - given a polynomial, commit to it
46+
assert!(g1_srs.len() >= coefs.len());
47+
// Todo implement multiplication with field elements as scalar mult.
48+
// Maybe having the scalar mult be around the base field like colin suggested is better
49+
50+
let mut commitment = AffinePoint::Infinity;
51+
for (coef, point) in coefs.iter().zip(g1_srs) {
52+
let res = point * *coef;
53+
// println!("res {:?}, of multiplying point {:?}, and coef {:?}", res, point, coef);
54+
println!("commitment {:?} before addition with {:?}", commitment, res);
55+
commitment = commitment + res;
56+
}
57+
commitment
58+
}
59+
3660
#[cfg(test)]
3761
mod tests {
3862
use super::*;
@@ -51,6 +75,7 @@ mod tests {
5175
AffinePoint::<PlutoCurve<GF101>>::new(GF101::new(68), GF101::new(27)),
5276
AffinePoint::<PlutoCurve<GF101>>::new(GF101::new(65), GF101::new(3)),
5377
];
78+
5479
assert_eq!(g1srs, expected_g1srs);
5580

5681
println!("g2srs {:?}", g2srs);
@@ -64,4 +89,33 @@ mod tests {
6489

6590
assert_eq!(g2srs, expected_g2srs);
6691
}
92+
93+
#[test]
94+
fn test_commit() {
95+
let (g1srs, _) = setup();
96+
// p(x) = (x-1)(x-2)(x-3)
97+
// p(x) = x^3 - 6x^2 + 11x - 6
98+
// -> -6 mod 17 is 11 so this is [1, 11, 11, 1]
99+
let coefficients = vec![11, 11, 11, 1];
100+
// g1srs[0] * 11 + g1srs[1] * 11 + g1srs[2] * 11 + g1srs[3] * 1
101+
let commit_1 = commit(coefficients, g1srs.clone());
102+
assert_eq!(commit_1, AffinePoint::<PlutoCurve<GF101>>::Infinity);
103+
104+
// p(x) = (x-1)(x-2)(x-3)(x-4)
105+
// p(x) = x^4 - 10x^3 + 35x^2 - 50x + 24
106+
// -> 24 mod 17 is 7
107+
// -> 50 mod 17 is 16
108+
// -> 35 mod 17 is 1
109+
// coefficients = [7, 16, 1, 11, 1]
110+
let coefficients = vec![7, 16, 1, 11, 1];
111+
// g1srs[0] * 7 + g1srs[1] * 16 + g1srs[2] * 1 + g1srs[3] * 11 + g1srs[4] * 1
112+
let commit_2 = commit(coefficients, g1srs.clone());
113+
assert_eq!(commit_2, AffinePoint::<PlutoCurve<GF101>>::new(GF101::new(32), GF101::new(59)));
114+
115+
// p(x) = x^2 + 2x + 3
116+
let coefficients = vec![3, 2, 1];
117+
// g1srs[0] * 3 + g1srs[1] * 2 + g1srs[2] * 1
118+
let commit_3 = commit(coefficients, g1srs);
119+
assert_eq!(commit_3, AffinePoint::<PlutoCurve<GF101>>::new(GF101::new(32), GF101::new(59)));
120+
}
67121
}

0 commit comments

Comments
 (0)