-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
57e82ed
commit 04575c4
Showing
4 changed files
with
260 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Code generated by scarb DO NOT EDIT. | ||
version = 1 | ||
|
||
[[package]] | ||
name = "garaga" | ||
version = "0.1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "garaga" | ||
version = "0.1.0" | ||
licence = "MIT" | ||
keywords = ["zk", "snarks", "curve", "pairing", "groth16", "plonk", "bls", "elliptic", "signature"] | ||
description = "State-of-the-art Elliptic Curve operations and SNARKS verification for Cairo & Starknet" | ||
readme = "../../README.md" | ||
repository = "https://github.com/keep-starknet-strange/garaga" | ||
|
||
# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
use core::circuit::{u96, u384}; | ||
|
||
struct G1Point { | ||
x: u384, | ||
y: u384, | ||
} | ||
|
||
struct Fq2 { | ||
a0: u384, | ||
a1: u384, | ||
} | ||
|
||
struct G2Point { | ||
x: Fq2, | ||
y: Fq2, | ||
} | ||
|
||
struct Curve { | ||
p: u384, // Prime modulus | ||
n: u384, // Order of the curve | ||
a: u384, // Weierstrass a parameter in eqn: y^2 = x^3 + ax + b | ||
b: u384, // Weierstrass b parameter in eqn: y^2 = x^3 + ax + b | ||
g: u384, // Generator of Fp. (Used to verify square roots) | ||
min_one: u384, // (-1) % p | ||
} | ||
|
||
const all_curves: [Curve; 5] = [BN254, BLS12_381, SECP256K1, SECP256R1, X25519]; | ||
|
||
|
||
const BN254: Curve = | ||
Curve { | ||
p: u384 { | ||
limb0: 0x6871ca8d3c208c16d87cfd47, | ||
limb1: 0xb85045b68181585d97816a91, | ||
limb2: 0x30644e72e131a029, | ||
limb3: 0x0 | ||
}, | ||
n: u384 { | ||
limb0: 0x79b9709143e1f593f0000001, | ||
limb1: 0xb85045b68181585d2833e848, | ||
limb2: 0x30644e72e131a029, | ||
limb3: 0x0 | ||
}, | ||
a: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
b: u384 { limb0: 0x3, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
g: u384 { limb0: 0x3, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
min_one: u384 { | ||
limb0: 0x6871ca8d3c208c16d87cfd46, | ||
limb1: 0xb85045b68181585d97816a91, | ||
limb2: 0x30644e72e131a029, | ||
limb3: 0x0 | ||
}, | ||
}; | ||
|
||
const BLS12_381: Curve = | ||
Curve { | ||
p: u384 { | ||
limb0: 0xb153ffffb9feffffffffaaab, | ||
limb1: 0x6730d2a0f6b0f6241eabfffe, | ||
limb2: 0x434bacd764774b84f38512bf, | ||
limb3: 0x1a0111ea397fe69a4b1ba7b6 | ||
}, | ||
n: u384 { | ||
limb0: 0xfffe5bfeffffffff00000001, | ||
limb1: 0x3339d80809a1d80553bda402, | ||
limb2: 0x73eda753299d7d48, | ||
limb3: 0x0 | ||
}, | ||
a: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
b: u384 { limb0: 0x4, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
g: u384 { limb0: 0x3, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
min_one: u384 { | ||
limb0: 0xb153ffffb9feffffffffaaaa, | ||
limb1: 0x6730d2a0f6b0f6241eabfffe, | ||
limb2: 0x434bacd764774b84f38512bf, | ||
limb3: 0x1a0111ea397fe69a4b1ba7b6 | ||
}, | ||
}; | ||
|
||
const SECP256K1: Curve = | ||
Curve { | ||
p: u384 { | ||
limb0: 0xfffffffffffffffefffffc2f, | ||
limb1: 0xffffffffffffffffffffffff, | ||
limb2: 0xffffffffffffffff, | ||
limb3: 0x0 | ||
}, | ||
n: u384 { | ||
limb0: 0xaf48a03bbfd25e8cd0364141, | ||
limb1: 0xfffffffffffffffebaaedce6, | ||
limb2: 0xffffffffffffffff, | ||
limb3: 0x0 | ||
}, | ||
a: u384 { limb0: 0x0, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
b: u384 { limb0: 0x7, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
g: u384 { limb0: 0x3, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
min_one: u384 { | ||
limb0: 0xfffffffffffffffefffffc2e, | ||
limb1: 0xffffffffffffffffffffffff, | ||
limb2: 0xffffffffffffffff, | ||
limb3: 0x0 | ||
}, | ||
}; | ||
|
||
const SECP256R1: Curve = | ||
Curve { | ||
p: u384 { | ||
limb0: 0xffffffffffffffffffffffff, limb1: 0x0, limb2: 0xffffffff00000001, limb3: 0x0 | ||
}, | ||
n: u384 { | ||
limb0: 0xa7179e84f3b9cac2fc632551, | ||
limb1: 0xffffffffffffffffbce6faad, | ||
limb2: 0xffffffff00000000, | ||
limb3: 0x0 | ||
}, | ||
a: u384 { | ||
limb0: 0xfffffffffffffffffffffffc, limb1: 0x0, limb2: 0xffffffff00000001, limb3: 0x0 | ||
}, | ||
b: u384 { | ||
limb0: 0xcc53b0f63bce3c3e27d2604b, | ||
limb1: 0xb3ebbd55769886bc651d06b0, | ||
limb2: 0x5ac635d8aa3a93e7, | ||
limb3: 0x0 | ||
}, | ||
g: u384 { limb0: 0x6, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
min_one: u384 { | ||
limb0: 0xfffffffffffffffffffffffe, limb1: 0x0, limb2: 0xffffffff00000001, limb3: 0x0 | ||
}, | ||
}; | ||
|
||
const X25519: Curve = | ||
Curve { | ||
p: u384 { | ||
limb0: 0xffffffffffffffffffffffed, | ||
limb1: 0xffffffffffffffffffffffff, | ||
limb2: 0x7fffffffffffffff, | ||
limb3: 0x0 | ||
}, | ||
n: u384 { | ||
limb0: 0xa2f79cd65812631a5cf5d3ed, | ||
limb1: 0x14def9de, | ||
limb2: 0x1000000000000000, | ||
limb3: 0x0 | ||
}, | ||
a: u384 { | ||
limb0: 0xaaaaaaaaaaaaaa984914a144, | ||
limb1: 0xaaaaaaaaaaaaaaaaaaaaaaaa, | ||
limb2: 0x2aaaaaaaaaaaaaaa, | ||
limb3: 0x0 | ||
}, | ||
b: u384 { | ||
limb0: 0x5ed097b4260b5e9c7710c864, | ||
limb1: 0x97b425ed097b425ed097b42, | ||
limb2: 0x7b425ed097b425ed, | ||
limb3: 0x0 | ||
}, | ||
g: u384 { limb0: 0x6, limb1: 0x0, limb2: 0x0, limb3: 0x0 }, | ||
min_one: u384 { | ||
limb0: 0xffffffffffffffffffffffec, | ||
limb1: 0xffffffffffffffffffffffff, | ||
limb2: 0x7fffffffffffffff, | ||
limb3: 0x0 | ||
}, | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
mod definitions; | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use core::traits::TryInto; | ||
use core::circuit::{ | ||
RangeCheck96, AddMod, MulMod, u96, CircuitElement, CircuitInput, CircuitDefinition, | ||
circuit_add, circuit_sub, circuit_mul, circuit_inverse, EvalCircuitResult, FillInputResult, | ||
InputAccumulatorTrait, CircuitDescriptorTrait, u384, CircuitOutputsTrait, CircuitModulus | ||
}; | ||
|
||
#[test] | ||
fn test_u96() { | ||
let a: u96 = 0x123; | ||
assert_eq!(a, 0x123); | ||
} | ||
|
||
#[test] | ||
fn test_builtins() { | ||
core::internal::require_implicit::<RangeCheck96>(); | ||
core::internal::require_implicit::<AddMod>(); | ||
core::internal::require_implicit::<MulMod>(); | ||
} | ||
|
||
#[test] | ||
fn test_circuit_success() { | ||
let in1 = CircuitElement::<CircuitInput<0>> {}; | ||
let in2 = CircuitElement::<CircuitInput<1>> {}; | ||
let add = circuit_add(in1, in2); | ||
let inv = circuit_inverse(add); | ||
let sub = circuit_sub(inv, in2); | ||
let mul = circuit_mul(inv, sub); | ||
let circ = (mul,); | ||
let inputs = circ.init(); | ||
|
||
let inputs = match inputs.fill_input([3, 0, 0, 0]) { | ||
FillInputResult::More(new_inputs) => new_inputs, | ||
FillInputResult::Done(_data) => { panic!("Expected more inputs") } | ||
}; | ||
let data = match inputs.fill_input([6, 0, 0, 0]) { | ||
FillInputResult::More(_new_inputs) => panic!("Expected Done"), | ||
FillInputResult::Done(data) => data | ||
}; | ||
|
||
let modulus = TryInto::<_, CircuitModulus>::try_into([7, 0, 0, 0]).unwrap(); | ||
let outputs = match circ.get_descriptor().eval(data, modulus) { | ||
EvalCircuitResult::Success(outputs) => { outputs }, | ||
EvalCircuitResult::Failure((_, _)) => { panic!("Expected success") } | ||
}; | ||
|
||
assert_eq!(outputs.get_output(add), u384 { limb0: 2, limb1: 0, limb2: 0, limb3: 0 }); | ||
assert_eq!(outputs.get_output(inv), u384 { limb0: 4, limb1: 0, limb2: 0, limb3: 0 }); | ||
assert_eq!(outputs.get_output(sub), u384 { limb0: 5, limb1: 0, limb2: 0, limb3: 0 }); | ||
assert_eq!(outputs.get_output(mul), u384 { limb0: 6, limb1: 0, limb2: 0, limb3: 0 }); | ||
} | ||
|
||
|
||
#[test] | ||
fn test_circuit_failure() { | ||
let in0 = CircuitElement::<CircuitInput<0>> {}; | ||
let out0 = circuit_inverse(in0); | ||
let circ = (out0,); | ||
let inputs = circ.init(); | ||
|
||
let data = match inputs.fill_input([11, 0, 0, 0]) { | ||
FillInputResult::More(_new_inputs) => panic!("Expected Done"), | ||
FillInputResult::Done(data) => data | ||
}; | ||
|
||
let modulus = TryInto::<_, CircuitModulus>::try_into([55, 0, 0, 0]).unwrap(); | ||
|
||
match circ.get_descriptor().eval(data, modulus) { | ||
EvalCircuitResult::Failure((_, _)) => {}, | ||
EvalCircuitResult::Success(_outputs) => { panic!("Expected failure"); } | ||
} | ||
} | ||
} |