Fix firmware size limits and refresh CI compatibility checks
Compact the existing STM32 field arithmetic and ESP-NOW tail-frame storage without removing features or lowering memory reserves. Refresh power-saving fixtures and pin official-app tests to a published archive.
This commit is contained in:
1 parent
cf98125c65
commit
c563c40c66
15 files changed
+494
-66
No files matched your search
+10
-1
@@ -9,6 +9,7 @@
|
||||
/*
|
||||
helper functions
|
||||
*/
|
||||
#if !defined(ED25519_COMPACT_FIELD) || !ED25519_COMPACT_FIELD
|
||||
static uint64_t load_3(const unsigned char *in) {
|
||||
uint64_t result;
|
||||
|
||||
@@ -29,6 +30,7 @@ static uint64_t load_4(const unsigned char *in) {
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -301,6 +303,7 @@ void fe_copy(fe h, const fe f) {
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(ED25519_COMPACT_FIELD) || !ED25519_COMPACT_FIELD
|
||||
void fe_frombytes(fe h, const unsigned char *s) {
|
||||
int64_t h0 = load_4(s);
|
||||
int64_t h1 = load_3(s + 4) << 6;
|
||||
@@ -368,6 +371,8 @@ void fe_frombytes(fe h, const unsigned char *s) {
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
void fe_invert(fe out, const fe z) {
|
||||
fe t0;
|
||||
fe t1;
|
||||
@@ -482,6 +487,7 @@ int fe_isnegative(const fe f) {
|
||||
|f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
|
||||
*/
|
||||
|
||||
#if !defined(ED25519_COMPACT_FIELD) || !ED25519_COMPACT_FIELD
|
||||
int fe_isnonzero(const fe f) {
|
||||
unsigned char s[32];
|
||||
unsigned char r;
|
||||
@@ -525,6 +531,7 @@ int fe_isnonzero(const fe f) {
|
||||
|
||||
return r != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -785,6 +792,7 @@ Postconditions:
|
||||
|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
*/
|
||||
|
||||
#if !defined(ED25519_COMPACT_FIELD) || !ED25519_COMPACT_FIELD
|
||||
void fe_mul121666(fe h, fe f) {
|
||||
int32_t f0 = f[0];
|
||||
int32_t f1 = f[1];
|
||||
@@ -852,7 +860,6 @@ Postconditions:
|
||||
|h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
|
||||
*/
|
||||
|
||||
#if !defined(ED25519_COMPACT_FIELD) || !ED25519_COMPACT_FIELD
|
||||
void fe_neg(fe h, const fe f) {
|
||||
int32_t f0 = f[0];
|
||||
int32_t f1 = f[1];
|
||||
@@ -1400,6 +1407,7 @@ Proof:
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(ED25519_COMPACT_FIELD) || !ED25519_COMPACT_FIELD
|
||||
void fe_tobytes(unsigned char *s, const fe h) {
|
||||
int32_t h0 = h[0];
|
||||
int32_t h1 = h[1];
|
||||
@@ -1506,3 +1514,4 @@ void fe_tobytes(unsigned char *s, const fe h) {
|
||||
s[30] = (unsigned char) (h9 >> 10);
|
||||
s[31] = (unsigned char) (h9 >> 18);
|
||||
}
|
||||
#endif
|
||||
+86
-15
@@ -1,15 +1,18 @@
|
||||
/*
|
||||
* Fixed-loop form of the ref10 field products in fe.c. Only the headless
|
||||
* STM32 Companion size recipes opt in; other builds keep the unrolled code.
|
||||
* Fixed-loop form of the ref10 field arithmetic in fe.c. The existing STM32
|
||||
* size recipes opt in; other builds keep the unrolled code.
|
||||
* The radix alternates 26 and 25 bits. Odd-by-odd products therefore have
|
||||
* weight 2, and terms beyond bit 254 fold back with weight 19, exactly as in
|
||||
* ref10. Product accumulation and the rounded carry order are unchanged.
|
||||
* ref10. Product accumulation, decoding, encoding and carry orders are unchanged.
|
||||
*
|
||||
* All loops, branches and array addresses depend only on public limb indices
|
||||
* or the public operation (multiply, square, double-square), not input values.
|
||||
* Under ref10's 1.65*2^26 / 1.65*2^25 input bounds, even doubled sums fit in
|
||||
* signed 64 bits. Outputs are written only after reading every input, so h
|
||||
* may alias f or g. No additional persistent RAM or heap is needed.
|
||||
* may alias f or g. No additional persistent RAM or heap is needed. Compared
|
||||
* with the unrolled forms, public-index loop overhead trades CPU time for
|
||||
* flash; the fixed number of field operations and secret-independent control
|
||||
* flow are retained for every opted-in Companion and Mini Repeater profile.
|
||||
*/
|
||||
|
||||
void fe_add(fe h, const fe f, const fe g) {
|
||||
@@ -48,6 +51,84 @@ void fe_cswap(fe f, fe g, unsigned int b) {
|
||||
}
|
||||
}
|
||||
|
||||
static void fe_compact_carry(fe h, int64_t limbs[10],
|
||||
const unsigned char *order, int count) {
|
||||
int i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
const int index = order[i];
|
||||
const int bits = 26 - (index & 1);
|
||||
const int64_t radix = (int64_t)1 << bits;
|
||||
const int64_t carry = (limbs[index] + radix / 2) >> bits;
|
||||
if (index == 9) limbs[0] += carry * 19;
|
||||
else limbs[index + 1] += carry;
|
||||
/* A carry may be negative; do not left-shift that signed value. */
|
||||
limbs[index] -= carry * radix;
|
||||
}
|
||||
for (i = 0; i < 10; ++i) h[i] = (int32_t)limbs[i];
|
||||
}
|
||||
|
||||
static const unsigned char fe_decode_carries[] = {9, 1, 3, 5, 7, 0, 2, 4, 6, 8};
|
||||
|
||||
void fe_frombytes(fe h, const unsigned char *s) {
|
||||
static const unsigned char offsets[] = {0, 4, 7, 10, 13, 16, 20, 23, 26, 29};
|
||||
static const unsigned char shifts[] = {0, 6, 5, 3, 2, 0, 7, 5, 4, 2};
|
||||
int64_t limbs[10];
|
||||
int i, j;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
uint32_t word = 0;
|
||||
const int count = i == 0 || i == 5 ? 4 : 3;
|
||||
for (j = 0; j < count; ++j)
|
||||
word |= (uint32_t)s[offsets[i] + j] << (j * 8);
|
||||
if (i == 9) word &= 8388607; /* Ignore the encoded sign bit. */
|
||||
limbs[i] = (int64_t)word << shifts[i];
|
||||
}
|
||||
fe_compact_carry(h, limbs, fe_decode_carries, sizeof(fe_decode_carries));
|
||||
}
|
||||
|
||||
void fe_mul121666(fe h, fe f) {
|
||||
int64_t limbs[10];
|
||||
int i;
|
||||
for (i = 0; i < 10; ++i) limbs[i] = (int64_t)f[i] * 121666;
|
||||
fe_compact_carry(h, limbs, fe_decode_carries, sizeof(fe_decode_carries));
|
||||
}
|
||||
|
||||
void fe_tobytes(unsigned char *s, const fe h) {
|
||||
int32_t limbs[10], q = (19 * h[9] + (1 << 24)) >> 25;
|
||||
int i, index = 0, offset = 0;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
limbs[i] = h[i];
|
||||
q = (limbs[i] + q) >> (26 - (i & 1));
|
||||
}
|
||||
limbs[0] += 19 * q;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
const int bits = 26 - (i & 1);
|
||||
const int32_t carry = limbs[i] >> bits;
|
||||
if (i < 9) limbs[i + 1] += carry;
|
||||
limbs[i] -= carry * ((int32_t)1 << bits);
|
||||
}
|
||||
/* Each byte crosses at most one public radix boundary. Normalized limbs
|
||||
* are nonnegative, and unsigned shifts avoid overflowing signed int32. */
|
||||
for (i = 0; i < 32; ++i) {
|
||||
uint32_t byte = (uint32_t)limbs[index] >> offset;
|
||||
offset += 8;
|
||||
if (offset >= 26 - (index & 1)) {
|
||||
offset -= 26 - (index & 1);
|
||||
++index;
|
||||
if (offset && index < 10)
|
||||
byte |= (uint32_t)limbs[index] << (8 - offset);
|
||||
}
|
||||
s[i] = (unsigned char)byte;
|
||||
}
|
||||
}
|
||||
|
||||
int fe_isnonzero(const fe f) {
|
||||
unsigned char bytes[32], value = 0;
|
||||
int i;
|
||||
fe_tobytes(bytes, f);
|
||||
for (i = 0; i < 32; ++i) value |= bytes[i];
|
||||
return value != 0;
|
||||
}
|
||||
|
||||
static void fe_compact_product(fe h, const fe f, const fe g, int doubled) {
|
||||
static const unsigned char carry_order[] = {0, 4, 1, 5, 2, 6, 3, 7, 4, 8, 9, 0};
|
||||
int64_t limbs[10] = {0};
|
||||
@@ -63,17 +144,7 @@ static void fe_compact_product(fe h, const fe f, const fe g, int doubled) {
|
||||
if (doubled) {
|
||||
for (i = 0; i < 10; ++i) limbs[i] += limbs[i];
|
||||
}
|
||||
for (i = 0; i < (int)sizeof(carry_order); ++i) {
|
||||
const int index = carry_order[i];
|
||||
const int bits = 26 - (index & 1);
|
||||
const int64_t radix = (int64_t)1 << bits;
|
||||
const int64_t carry = (limbs[index] + radix / 2) >> bits;
|
||||
if (index == 9) limbs[0] += carry * 19;
|
||||
else limbs[index + 1] += carry;
|
||||
/* A carry may be negative; do not left-shift that signed value. */
|
||||
limbs[index] -= carry * radix;
|
||||
}
|
||||
for (i = 0; i < 10; ++i) h[i] = (int32_t)limbs[i];
|
||||
fe_compact_carry(h, limbs, carry_order, sizeof(carry_order));
|
||||
}
|
||||
|
||||
void fe_mul(fe h, const fe f, const fe g) {
|
||||
|
||||
Reference in new issue
Block a user