Skip to content

Commit 51b476b

Browse files
committed
some code rfks
1 parent c803815 commit 51b476b

File tree

3 files changed

+57
-25
lines changed

3 files changed

+57
-25
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ P(x) = 82*x^4 + 81*x^3 + 83*x^2 + 88*x + 54
7878
P(x) / T(x) = 82*x + 88
7979
```
8080

81-
We can also design circuits with the existing gates (see [this example](./tests/circuits_test.rs)) and then print a wire that you have to see its gates, everything is composed of `+` and `*` gates only!
81+
We can also design circuits with the existing gates (see [this example](./tests/circuits_test.rs)) and then print a wire's lavel to see its gates, everything is composed of `+` and `*` only!
8282

8383
```py
8484
# for equal wires a, b in a field of order 97

src/circuits/wire.rs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,55 @@ use lambdaworks_math::field::{
33
traits::{IsField, IsPrimeField},
44
};
55

6+
// TODO: we should add a `Context` ref field here that handles
7+
// wire namings so that there are no collisions etc.
8+
9+
/// A circuit "wire" that holds a value and a label.
10+
///
11+
/// It has addition, multiplication, subtraction, and negation operations overloaded
12+
/// so that the label is updated to indicate the operation w.r.t addition gates and
13+
/// multiplication gates.
14+
///
15+
/// You can create constant wires (which are labeled by numbers) or named wires
16+
/// with a label that you provide.
17+
///
18+
/// You can use `u64` values while creating constants, or even wires, which are implement
19+
/// `Into` to become a field element in the corresponding field.
620
#[derive(Clone, Debug)]
721
pub struct Wire<F: IsField> {
822
pub label: String,
923
pub value: FieldElement<F>,
1024
}
1125

1226
impl<F: IsPrimeField> Wire<F> {
13-
pub fn constant(value: FieldElement<F>) -> Self {
27+
pub fn constant(value: impl Into<FieldElement<F>>) -> Self {
28+
let value = value.into();
1429
Self {
1530
label: value.representative().to_string(),
1631
value,
1732
}
1833
}
1934

20-
pub fn new(value: impl Into<FieldElement<F>>, label: String) -> Self {
35+
pub fn new(value: impl Into<FieldElement<F>>, label: impl ToString) -> Self {
2136
Self {
22-
label,
37+
label: label.to_string(),
2338
value: value.into(),
2439
}
2540
}
2641

27-
#[inline]
42+
#[inline(always)]
2843
pub fn one() -> Self {
29-
Self::constant(FieldElement::<F>::one())
44+
Self::constant(1)
3045
}
3146

32-
#[inline]
47+
#[inline(always)]
3348
pub fn neg_one() -> Self {
3449
Self::constant(-FieldElement::<F>::one())
3550
}
3651

37-
#[inline]
52+
#[inline(always)]
3853
pub fn zero() -> Self {
39-
Self::constant(FieldElement::<F>::zero())
54+
Self::constant(0)
4055
}
4156
}
4257

@@ -48,12 +63,6 @@ impl<F: IsField> PartialEq for Wire<F> {
4863

4964
impl<F: IsField> Eq for &Wire<F> {}
5065

51-
impl<F: IsPrimeField> std::fmt::Display for Wire<F> {
52-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53-
write!(f, "{}: {}", self.label, self.value.representative())
54-
}
55-
}
56-
5766
impl<F: IsField> std::ops::Add<Wire<F>> for Wire<F> {
5867
type Output = Wire<F>;
5968

@@ -123,3 +132,9 @@ impl<'a, F: IsPrimeField> std::ops::Neg for &'a Wire<F> {
123132
&Wire::<F>::neg_one() * self
124133
}
125134
}
135+
136+
impl<F: IsPrimeField> From<u64> for Wire<F> {
137+
fn from(value: u64) -> Self {
138+
Wire::constant(value)
139+
}
140+
}

tests/circuits_test.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,41 @@
11
use lambdaworks_math::field::fields::u64_prime_field::U64PrimeField;
22
use mpbc_arithmetic_circuits::*;
33

4+
// some arbitrary field order
45
const ORDER: u64 = 97;
5-
type F = U64PrimeField<ORDER>; // Example field with a small prime for simplicity
6+
type F = U64PrimeField<ORDER>;
67
type W = circuits::Wire<F>;
78

89
#[test]
9-
fn test_main() {
10-
let a = W::new(23, "a".to_string());
11-
let b = W::new(23, "b".to_string());
12-
let c = W::new(55, "c".to_string());
10+
fn test_is_equal() {
11+
let a = W::new(23, "a");
12+
let b = W::new(23, "b");
13+
let c = W::new(55, "c");
1314

1415
let a_is_b = circuits::comparators::is_equal(&a, &b);
15-
println!("a == b is given by {}", a_is_b);
16+
assert_eq!(a_is_b.label, "(1+(96*((a+(96*b))*0)))");
1617

1718
let b_is_c = circuits::comparators::is_equal(&b, &c);
18-
println!("b == c is given by {}", b_is_c);
19+
assert_eq!(b_is_c.label, "(1+(96*((b+(96*c))*(b+(96*c))_neg)))");
20+
}
1921

20-
// create r1cs
21-
let cc = c.clone() * c.clone();
22+
#[test]
23+
fn test_c_cube() {
24+
let c = W::new(55, "c");
25+
let cc = &c * &c;
2226
let ccc = cc * c;
23-
println!("c^3 is given by {}", ccc);
27+
28+
assert_eq!(ccc.label, "((c*c)*c)");
29+
assert_eq!(ccc.value, (55 * 55 * 55).into());
30+
}
31+
32+
#[test]
33+
fn test_vitalik_example() {
34+
// we are constructing: x^3 + x + 5 = 35
35+
let x = W::new(3, "x");
36+
let xx = &x * &x;
37+
let ans = (&xx * &x) + x + 5.into();
38+
39+
assert_eq!(ans.label, "((((x*x)*x)+x)+5)");
40+
assert_eq!(ans.value, 35.into());
2441
}

0 commit comments

Comments
 (0)