snarkvm_circuit_types_group/
neg.rs1use super::*;
17
18impl<E: Environment> Neg for Group<E> {
19 type Output = Self;
20
21 fn neg(self) -> Self::Output {
23 Group { x: -self.x, y: self.y }
24 }
25}
26
27impl<E: Environment> Neg for &Group<E> {
28 type Output = Group<E>;
29
30 fn neg(self) -> Self::Output {
32 -(self.clone())
33 }
34}
35
36impl<E: Environment> Metrics<dyn Neg<Output = Group<E>>> for Group<E> {
37 type Case = Mode;
38
39 fn count(_case: &Self::Case) -> Count {
40 Count::is(0, 0, 0, 0)
41 }
42}
43
44impl<E: Environment> OutputMode<dyn Neg<Output = Group<E>>> for Group<E> {
45 type Case = Mode;
46
47 fn output_mode(case: &Self::Case) -> Mode {
48 match case {
49 Mode::Constant => Mode::Constant,
50 _ => Mode::Private,
51 }
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use snarkvm_circuit_environment::Circuit;
59
60 const ITERATIONS: u64 = 100;
61
62 fn check_neg(
63 name: &str,
64 expected: console::Group<<Circuit as Environment>::Network>,
65 candidate_input: Group<Circuit>,
66 ) {
67 Circuit::scope(name, || {
68 let mode = candidate_input.eject_mode();
69 let candidate_output = -candidate_input;
70 assert_eq!(expected, candidate_output.eject_value());
71 assert_count!(Neg(Group) => Group, &mode);
72 assert_output_mode!(Neg(Group) => Group, &mode, candidate_output);
73 });
74 }
75
76 #[test]
77 fn test_neg_constant() {
78 let mut rng = TestRng::default();
79
80 for i in 0..ITERATIONS {
81 let point: console::Group<_> = Uniform::rand(&mut rng);
83 let expected: console::Group<_> = -point;
84
85 let candidate_input = Group::<Circuit>::new(Mode::Constant, point);
86 check_neg(&format!("NEG Constant {i}"), expected, candidate_input);
87 }
88 }
89
90 #[test]
91 fn test_neg_public() {
92 let mut rng = TestRng::default();
93
94 for i in 0..ITERATIONS {
95 let point: console::Group<_> = Uniform::rand(&mut rng);
97 let expected: console::Group<_> = -point;
98
99 let candidate_input = Group::<Circuit>::new(Mode::Public, point);
100 check_neg(&format!("NEG Public {i}"), expected, candidate_input);
101 }
102 }
103
104 #[test]
105 fn test_neg_private() {
106 let mut rng = TestRng::default();
107
108 for i in 0..ITERATIONS {
109 let point: console::Group<_> = Uniform::rand(&mut rng);
111 let expected: console::Group<_> = -point;
112
113 let candidate_input = Group::<Circuit>::new(Mode::Private, point);
114 check_neg(&format!("NEG Private {i}"), expected, candidate_input);
115 }
116 }
117
118 #[test]
119 fn test_zero() {
120 let expected = console::Group::<<Circuit as Environment>::Network>::zero();
121
122 let candidate_input = Group::<Circuit>::zero();
123 check_neg("NEG Constant Zero", expected, candidate_input);
124
125 let candidate_input = Group::<Circuit>::new(Mode::Public, expected);
126 check_neg("NEG Public Zero", expected, candidate_input);
127
128 let candidate_input = Group::<Circuit>::new(Mode::Private, expected);
129 check_neg("NEG Private Zero", expected, candidate_input);
130 }
131}