ring/ec/suite_b/ops/
elem.rs1use crate::{
16 arithmetic::{
17 limbs_from_hex,
18 montgomery::{Encoding, ProductEncoding},
19 },
20 limb::{Limb, LIMB_BITS},
21};
22use core::marker::PhantomData;
23
24#[derive(Clone, Copy)]
27pub struct Elem<M, E: Encoding> {
28 pub(super) limbs: [Limb; MAX_LIMBS],
30
31 pub(super) m: PhantomData<M>,
33
34 pub(super) encoding: PhantomData<E>,
37}
38
39impl<M, E: Encoding> Elem<M, E> {
40 pub fn zero() -> Self {
44 Self {
45 limbs: [0; MAX_LIMBS],
46 m: PhantomData,
47 encoding: PhantomData,
48 }
49 }
50
51 pub const fn from_hex(hex: &str) -> Self {
52 Elem {
53 limbs: limbs_from_hex(hex),
54 m: PhantomData,
55 encoding: PhantomData,
56 }
57 }
58}
59
60#[inline]
61pub fn mul_mont<M, EA: Encoding, EB: Encoding>(
62 f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
63 a: &Elem<M, EA>,
64 b: &Elem<M, EB>,
65) -> Elem<M, <(EA, EB) as ProductEncoding>::Output>
66where
67 (EA, EB): ProductEncoding,
68{
69 binary_op(f, a, b)
70}
71
72#[inline]
74pub fn binary_op<M, EA: Encoding, EB: Encoding, ER: Encoding>(
75 f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
76 a: &Elem<M, EA>,
77 b: &Elem<M, EB>,
78) -> Elem<M, ER> {
79 let mut r = Elem {
80 limbs: [0; MAX_LIMBS],
81 m: PhantomData,
82 encoding: PhantomData,
83 };
84 unsafe { f(r.limbs.as_mut_ptr(), a.limbs.as_ptr(), b.limbs.as_ptr()) }
85 r
86}
87
88#[inline]
90pub fn binary_op_assign<M, EA: Encoding, EB: Encoding>(
91 f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
92 a: &mut Elem<M, EA>,
93 b: &Elem<M, EB>,
94) {
95 unsafe { f(a.limbs.as_mut_ptr(), a.limbs.as_ptr(), b.limbs.as_ptr()) }
96}
97
98#[inline]
100pub fn unary_op<M, E: Encoding>(
101 f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
102 a: &Elem<M, E>,
103) -> Elem<M, E> {
104 let mut r = Elem {
105 limbs: [0; MAX_LIMBS],
106 m: PhantomData,
107 encoding: PhantomData,
108 };
109 unsafe { f(r.limbs.as_mut_ptr(), a.limbs.as_ptr()) }
110 r
111}
112
113#[inline]
115pub fn unary_op_assign<M, E: Encoding>(
116 f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb),
117 a: &mut Elem<M, E>,
118) {
119 unsafe { f(a.limbs.as_mut_ptr(), a.limbs.as_ptr()) }
120}
121
122#[inline]
124pub fn unary_op_from_binary_op_assign<M, E: Encoding>(
125 f: unsafe extern "C" fn(r: *mut Limb, a: *const Limb, b: *const Limb),
126 a: &mut Elem<M, E>,
127) {
128 unsafe { f(a.limbs.as_mut_ptr(), a.limbs.as_ptr(), a.limbs.as_ptr()) }
129}
130
131pub const MAX_LIMBS: usize = (384 + (LIMB_BITS - 1)) / LIMB_BITS;