github.com/cloudflare/circl@v1.5.0/kem/frodo/frodo640shake/util.go (about) 1 package frodo640shake 2 3 func add(out *nbarByNbarU16, lhs *nbarByNbarU16, rhs *nbarByNbarU16) { 4 for i := 0; i < len(out); i++ { 5 out[i] = (lhs[i] + rhs[i]) & logQMask 6 } 7 } 8 9 func sub(out *nbarByNbarU16, lhs *nbarByNbarU16, rhs *nbarByNbarU16) { 10 for i := 0; i < len(out); i++ { 11 out[i] = (lhs[i] - rhs[i]) & logQMask 12 } 13 } 14 15 func pack(out []byte, in []uint16) { 16 j := 0 17 for i := 0; (i * 8) < len(in); i++ { 18 in0 := in[i*8] & logQMask 19 in1 := in[(i*8)+1] & logQMask 20 in2 := in[(i*8)+2] & logQMask 21 in3 := in[(i*8)+3] & logQMask 22 in4 := in[(i*8)+4] & logQMask 23 in5 := in[(i*8)+5] & logQMask 24 in6 := in[(i*8)+6] & logQMask 25 in7 := in[(i*8)+7] & logQMask 26 27 out[j] |= byte(in0 >> 7) 28 out[j+1] = (byte(in0&0x7F) << 1) | byte(in1>>14) 29 30 out[j+2] = byte(in1 >> 6) 31 out[j+3] = (byte(in1&0x3F) << 2) | byte(in2>>13) 32 33 out[j+4] = byte(in2 >> 5) 34 out[j+5] = (byte(in2&0x1F) << 3) | byte(in3>>12) 35 36 out[j+6] = byte(in3 >> 4) 37 out[j+7] = (byte(in3&0x0F) << 4) | byte(in4>>11) 38 39 out[j+8] = byte(in4 >> 3) 40 out[j+9] = (byte(in4&0x07) << 5) | byte(in5>>10) 41 42 out[j+10] = byte(in5 >> 2) 43 out[j+11] = (byte(in5&0x03) << 6) | byte(in6>>9) 44 45 out[j+12] = byte(in6 >> 1) 46 out[j+13] = (byte(in6&0x01) << 7) | byte(in7>>8) 47 48 out[j+14] = byte(in7) 49 j += 15 50 } 51 } 52 53 func unpack(out []uint16, in []byte) { 54 j := 0 55 for i := 0; (i * 15) < len(in); i++ { 56 in0 := in[i*15] 57 in1 := in[(i*15)+1] 58 in2 := in[(i*15)+2] 59 in3 := in[(i*15)+3] 60 in4 := in[(i*15)+4] 61 in5 := in[(i*15)+5] 62 in6 := in[(i*15)+6] 63 in7 := in[(i*15)+7] 64 in8 := in[(i*15)+8] 65 in9 := in[(i*15)+9] 66 in10 := in[(i*15)+10] 67 in11 := in[(i*15)+11] 68 in12 := in[(i*15)+12] 69 in13 := in[(i*15)+13] 70 in14 := in[(i*15)+14] 71 72 out[j] = (uint16(in0) << 7) | (uint16(in1&0xFE) >> 1) 73 out[j+1] = (uint16(in1&0x1) << 14) | (uint16(in2) << 6) | (uint16(in3&0xFC) >> 2) 74 75 out[j+2] = (uint16(in3&0x03) << 13) | (uint16(in4) << 5) | (uint16(in5&0xF8) >> 3) 76 out[j+3] = (uint16(in5&0x07) << 12) | (uint16(in6) << 4) | (uint16(in7&0xF0) >> 4) 77 78 out[j+4] = (uint16(in7&0x0F) << 11) | (uint16(in8) << 3) | (uint16(in9&0xE0) >> 5) 79 out[j+5] = (uint16(in9&0x1F) << 10) | (uint16(in10) << 2) | (uint16(in11&0xC0) >> 6) 80 81 out[j+6] = (uint16(in11&0x3F) << 9) | (uint16(in12) << 1) | (uint16(in13&0x80) >> 7) 82 out[j+7] = (uint16(in13&0x7F) << 8) | uint16(in14) 83 j += 8 84 } 85 } 86 87 func encodeMessage(out *nbarByNbarU16, msg *[messageSize]byte) { 88 extractedBitsMask := uint16((1 << extractedBits) - 1) 89 outPos := 0 90 91 for i := 0; (i * 2) < len(msg); i++ { 92 in := uint16(msg[i*2]) | (uint16(msg[(i*2)+1]) << 8) 93 for j := 0; j < (16 / extractedBits); j++ { // 16 = bit size of out[i] 94 out[outPos] = (in & extractedBitsMask) << (logQ - extractedBits) 95 outPos++ 96 97 in >>= extractedBits 98 } 99 } 100 } 101 102 func decodeMessage(out *[messageSize]byte, msg *nbarByNbarU16) { 103 extractedBitsMask := uint16((1 << extractedBits) - 1) 104 msgPos := 0 105 106 for i := 0; i < len(out); i++ { 107 for j := 0; j < (8 / extractedBits); j++ { 108 temp := (msg[msgPos] & logQMask) + (1 << (logQ - extractedBits - 1)) 109 temp >>= (logQ - extractedBits) 110 temp &= extractedBitsMask 111 out[i] |= byte(temp) << (j * extractedBits) 112 msgPos++ 113 } 114 } 115 } 116 117 func mulAddSBPlusE(out *nbarByNbarU16, s []uint16, b *nByNbarU16, e []uint16) { 118 // Multiply by s on the left 119 // Inputs: b (N x N_BAR), s (N_BAR x N), e (N_BAR x N_BAR) 120 // Output: out = s*b + e (N_BAR x N_BAR) 121 122 for k := 0; k < paramNbar; k++ { 123 for i := 0; i < paramNbar; i++ { 124 out[k*paramNbar+i] = e[k*paramNbar+i] 125 for j := 0; j < paramN; j++ { 126 out[k*paramNbar+i] += s[k*paramN+j] * b[j*paramNbar+i] 127 } 128 out[k*paramNbar+i] = out[k*paramNbar+i] & logQMask 129 } 130 } 131 } 132 133 func mulBS(out *nbarByNbarU16, b *nbarByNU16, s *nByNbarU16) { 134 for i := 0; i < paramNbar; i++ { 135 for j := 0; j < paramNbar; j++ { 136 out[i*paramNbar+j] = 0 137 for k := 0; k < paramN; k++ { 138 out[i*paramNbar+j] += b[i*paramN+k] * s[j*paramN+k] 139 } 140 out[i*paramNbar+j] = out[i*paramNbar+j] & logQMask 141 } 142 } 143 } 144 145 func ctCompareU16(lhs []uint16, rhs []uint16) int { 146 // Compare lhs and rhs in constant time. 147 // Returns 0 if they are equal, 1 otherwise. 148 if len(lhs) != len(rhs) { 149 return 1 150 } 151 152 var v uint16 153 154 for i := range lhs { 155 v |= lhs[i] ^ rhs[i] 156 } 157 158 return int((v | -v) >> 15) 159 }