PRCYCoin  2.0.0.7rc1
P2P Digital Currency
scalar_low_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2015 Andrew Poelstra *
3  * Distributed under the MIT software license, see the accompanying *
4  * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5  **********************************************************************/
6 
7 #ifndef SECP256K1_SCALAR_REPR_IMPL_H
8 #define SECP256K1_SCALAR_REPR_IMPL_H
9 
10 #include "scalar.h"
11 
12 #include <string.h>
13 
14 SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) {
15  return !(*a & 1);
16 }
17 
18 SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; }
19 SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; }
20 SECP256K1_INLINE static void secp256k1_scalar_set_u64(secp256k1_scalar *r, uint64_t v) { *r = v % EXHAUSTIVE_TEST_ORDER; }
21 
22 SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
23  if (offset < 32)
24  return ((*a >> offset) & ((((uint32_t)1) << count) - 1));
25  else
26  return 0;
27 }
28 
29 SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) {
30  return secp256k1_scalar_get_bits(a, offset, count);
31 }
32 
33 SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; }
34 
35 static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) {
36  *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER;
37  return *r < *b;
38 }
39 
40 static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) {
41  if (flag && bit < 32)
42  *r += (1 << bit);
43 #ifdef VERIFY
44  VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0);
45 #endif
46 }
47 
48 static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) {
49  const int base = 0x100 % EXHAUSTIVE_TEST_ORDER;
50  int i;
51  *r = 0;
52  for (i = 0; i < 32; i++) {
53  *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER;
54  }
55  /* just deny overflow, it basically always happens */
56  if (overflow) *overflow = 0;
57 }
58 
59 static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) {
60  memset(bin, 0, 32);
61  bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a;
62 }
63 
64 SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) {
65  return *a == 0;
66 }
67 
68 static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) {
69  if (*a == 0) {
70  *r = 0;
71  } else {
72  *r = EXHAUSTIVE_TEST_ORDER - *a;
73  }
74 }
75 
76 SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) {
77  return *a == 1;
78 }
79 
80 static int secp256k1_scalar_is_high(const secp256k1_scalar *a) {
81  return *a > EXHAUSTIVE_TEST_ORDER / 2;
82 }
83 
84 static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
85  if (flag) secp256k1_scalar_negate(r, r);
86  return flag ? -1 : 1;
87 }
88 
89 static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) {
90  *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER;
91 }
92 
93 static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) {
94  int ret;
95  VERIFY_CHECK(n > 0);
96  VERIFY_CHECK(n < 16);
97  ret = *r & ((1 << n) - 1);
98  *r >>= n;
99  return ret;
100 }
101 
102 static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) {
103  *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER;
104 }
105 
106 static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) {
107  *r1 = *a;
108  *r2 = 0;
109 }
110 
111 SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) {
112  return *a == *b;
113 }
114 
115 SECP256K1_INLINE static void secp256k1_scalar_chacha20(secp256k1_scalar *r1, secp256k1_scalar *r2, const unsigned char *seed, uint64_t n) {
116  *r1 = (seed[0] + n) % EXHAUSTIVE_TEST_ORDER;
117  *r2 = (seed[1] + n) % EXHAUSTIVE_TEST_ORDER;
118 }
119 
120 #endif /* SECP256K1_SCALAR_REPR_IMPL_H */
VERIFY_CHECK
#define VERIFY_CHECK(cond)
Definition: util.h:61
EXHAUSTIVE_TEST_ORDER
#define EXHAUSTIVE_TEST_ORDER
Definition: tests_exhaustive.c:20
b
void const uint64_t * b
Definition: field_5x52_asm_impl.h:10
r
void const uint64_t uint64_t * r
Definition: field_5x52_asm_impl.h:10
secp256k1_scalar
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
scalar.h
SECP256K1_INLINE
#define SECP256K1_INLINE
Definition: secp256k1.h:23