int main(int argc, char *argv[]) { long long int n = glong(), i, maxbit, j, k, tmp; long long int a[100005], t, ans = 0; for (i = 0; i < n; ++i) { a[i] = glong(); } qsort((void*)a, n, sizeof(long long int), longlongintcmp); i = 0; while ((i < n) && (msb(a[i]))) { j = i + 1; t = msb(a[i]); while((j < n) && (t == msb(a[j]))) { a[j] ^= a[i]; j++; } qsort((void*)a, n, sizeof(long long int), longlongintcmp); i++; } for(i = 0; i < n; ++i) if((ans ^ a[i]) > ans) ans = ans ^ a[i]; printf("%lld\n", ans); return 0; }
static int pxa_gpio_irq(void) { word_t mask; int irq; mask = PXA_GEDR0 & (~0x3); if (mask) { irq = msb(mask); PXA_GEDR0 = (1UL << irq); return irq - 2; } mask = PXA_GEDR1; if (mask) { irq = msb(mask); PXA_GEDR1 = (1UL << irq); return 32 + irq - 2; } mask = PXA_GEDR2; if (mask) { irq = msb(mask); PXA_GEDR2 = (1UL << irq); return 64 + irq - 2; } return -1; }
Value Entry::shelter_storm(const Position& pos, Square ksq) { const Color Them = (Us == WHITE ? BLACK : WHITE); Value safety = MaxSafetyBonus; Bitboard b = pos.pieces(PAWN) & (in_front_bb(Us, rank_of(ksq)) | rank_bb(ksq)); Bitboard ourPawns = b & pos.pieces(Us); Bitboard theirPawns = b & pos.pieces(Them); Rank rkUs, rkThem; File kf = file_of(ksq); kf = (kf == FILE_A) ? FILE_B : (kf == FILE_H) ? FILE_G : kf; for (int f = kf - 1; f <= kf + 1; f++) { b = ourPawns & FileBB[f]; rkUs = b ? relative_rank(Us, Us == WHITE ? lsb(b) : msb(b)) : RANK_1; safety -= ShelterWeakness[rkUs]; b = theirPawns & FileBB[f]; rkThem = b ? relative_rank(Us, Us == WHITE ? lsb(b) : msb(b)) : RANK_1; safety -= StormDanger[rkUs == RANK_1 ? 0 : rkThem == rkUs + 1 ? 2 : 1][rkThem]; } return safety; }
/* * si4713_tx_rds_buff - Loads the RDS group buffer FIFO or circular buffer. * @sdev: si4713_device structure for the device we are communicating * @mode: the buffer operation mode. * @rdsb: RDS Block B * @rdsc: RDS Block C * @rdsd: RDS Block D * @cbleft: returns the number of available circular buffer blocks minus the * number of used circular buffer blocks. */ static int si4713_tx_rds_buff(struct si4713_device *sdev, u8 mode, u16 rdsb, u16 rdsc, u16 rdsd, s8 *cbleft) { int err; u8 val[SI4713_RDSBUFF_NRESP]; const u8 args[SI4713_RDSBUFF_NARGS] = { mode & SI4713_RDSBUFF_MODE_MASK, msb(rdsb), lsb(rdsb), msb(rdsc), lsb(rdsc), msb(rdsd), lsb(rdsd), }; err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_BUFF, args, ARRAY_SIZE(args), val, ARRAY_SIZE(val), DEFAULT_TIMEOUT); if (!err) { v4l2_dbg(1, debug, &sdev->sd, "%s: status=0x%02x\n", __func__, val[0]); *cbleft = (s8)val[2] - val[3]; v4l2_dbg(1, debug, &sdev->sd, "%s: response: interrupts" " 0x%02x cb avail: %d cb used %d fifo avail" " %d fifo used %d\n", __func__, val[1], val[2], val[3], val[4], val[5]); } return err; }
void ModbusRtu::_writeRegister(ModbusRtu::FunctionCode function, quint8 slaveAddress, quint16 reg, quint16 value) { Q_ASSERT(mState == Idle); QByteArray frame; frame.reserve(8); frame.append(static_cast<char>(slaveAddress)); frame.append(static_cast<char>(function)); frame.append(static_cast<char>(msb(reg))); frame.append(static_cast<char>(lsb(reg))); frame.append(static_cast<char>(msb(value))); frame.append(static_cast<char>(lsb(value))); send(frame); }
void ModbusRtu::_readRegisters(ModbusRtu::FunctionCode function, quint8 slaveAddress, quint16 startReg, quint16 count) { Q_ASSERT(mState == Idle); QByteArray frame; frame.reserve(8); frame.append(static_cast<char>(slaveAddress)); frame.append(static_cast<char>(function)); frame.append(static_cast<char>(msb(startReg))); frame.append(static_cast<char>(lsb(startReg))); frame.append(static_cast<char>(msb(count))); frame.append(static_cast<char>(lsb(count))); send(frame); }
int main() { uint64 a; int k,l; scanf("%d",&k); while(k>0) { l=0; scanf("%llu",&a); while(a>1) { if( isPow2(a) ) { a/=2; } else { a=a-(1LLU<<msb(a)); } l++; // printf("%llu\n",a); } if(l%2) { printf("Louise\n"); } else { printf("Richard\n"); } k--; } return 0; }
inline I restricted_multiply(cpp_int& result, const cpp_int& a, const cpp_int& b, I max_bits, boost::int64_t& error) { result = a * b; I gb = msb(result); I rshift = 0; if(gb > max_bits) { rshift = gb - max_bits; I lb = lsb(result); int roundup = 0; // The error rate increases by the error of both a and b, // this may be overly pessimistic in many case as we're assuming // that a and b have the same level of uncertainty... if(lb < rshift) error = error ? error * 2 : 1; if(rshift) { BOOST_ASSERT(rshift < INT_MAX); if(bit_test(result, static_cast<unsigned>(rshift - 1))) { if(lb == rshift - 1) roundup = 1; else roundup = 2; } result >>= rshift; } if((roundup == 2) || ((roundup == 1) && (result.backend().limbs()[0] & 1))) ++result; }
void Drf1600::writePanId(quint16 panId) { quint8 Msg[6] = { 0xFC, 0x02, 0x91, 0x01 }; Msg[4] = msb(panId); Msg[5] = lsb(panId); send(WritePanId, 2, Msg, sizeof(Msg)/sizeof(Msg[0])); }
// renvoie le XOR de n_bytes octets de flux uint64_t OutputFeedbackMode(int n_bytes){ vLog Sum[4]; v32 Poly[8]; uint64_t x = 0; int count = 0; uint64_t FinalOutput = 0; while(count < n_bytes) { ComputeSubsetSum_tabulated(x, Sum); // Extraction du flux ConvertSubsetSumToCoefficients(Sum, Poly); uint16_t M[8]; for(int i = 0; i < 8; i++) { M[i] = msb(Poly[i]); } // apply the BCH code v16 biased = {M[0], M[1], M[2], M[3], M[4], M[5], M[6], M[7]}; x = BCH128to64_clmul(biased); FinalOutput ^= x; count += 8; } return FinalOutput; }
void main(void) { struct vsf_module_t *module; struct vsf_module_info_t *minfo = (struct vsf_module_info_t *)APPCFG_MODULES_ADDR; int32_t pagesize; vsf_enter_critical(); vsfhal_core_init(NULL); vsfhal_flash_capacity(0, (uint32_t*)&pagesize, NULL); pagesize = msb(pagesize); vsf_bufmgr_init(app.bufmgr_buffer, sizeof(app.bufmgr_buffer)); // register modules while (minfo->entry != 0xFFFFFFFF) { module = vsf_bufmgr_malloc(sizeof(struct vsf_module_t)); if (NULL == module) { break; } module->flash = minfo; minfo = (struct vsf_module_info_t *)((uint8_t *)minfo +\ ((minfo->size + (1 << pagesize) - 1) & ~((1 << pagesize) - 1))); vsf_module_register(module); } vsf_module_load("vsf.os", true); // vsfos module SHALL never return; }
void TranspositionTable::resize(size_t mbSize) { size_t newClusterCount = size_t(1) << msb((mbSize * 1024 * 1024) / sizeof(Cluster)); if (newClusterCount == clusterCount) return; clusterCount = newClusterCount; mem = nullptr; FREE_MEM(mem); CREATE_MEM2(&mem, clusterCount * sizeof(Cluster)); large_use = true; if (!mem) { free(mem); mem = calloc(clusterCount * sizeof(Cluster) + CacheLineSize - 1, 1); large_use = false; } if (!mem) { std::cerr << "Failed to allocate " << mbSize << "MB for transposition table." << std::endl; exit(EXIT_FAILURE); } table = (Cluster*)((uintptr_t(mem) + CacheLineSize - 1) & ~(CacheLineSize - 1)); }
/* * si4713_tx_tune_freq - Sets the state of the RF carrier and sets the tuning * frequency between 76 and 108 MHz in 10 kHz units and * steps of 50 kHz. * @sdev: si4713_device structure for the device we are communicating * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz) */ static int si4713_tx_tune_freq(struct si4713_device *sdev, u16 frequency) { int err; u8 val[SI4713_TXFREQ_NRESP]; /* * .First byte = 0 * .Second byte = frequency's MSB * .Third byte = frequency's LSB */ const u8 args[SI4713_TXFREQ_NARGS] = { 0x00, msb(frequency), lsb(frequency), }; err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_FREQ, args, ARRAY_SIZE(args), val, ARRAY_SIZE(val), DEFAULT_TIMEOUT); if (err < 0) return err; v4l2_dbg(1, debug, &sdev->sd, "%s: frequency=0x%02x status=0x%02x\n", __func__, frequency, val[0]); err = si4713_wait_stc(sdev, TIMEOUT_TX_TUNE); if (err < 0) return err; return compose_u16(args[1], args[2]); }
/* * si4713_read_property - reads a si4713 property * @sdev: si4713_device structure for the device we are communicating * @prop: property identification number * @pv: property value to be returned on success */ static int si4713_read_property(struct si4713_device *sdev, u16 prop, u32 *pv) { int err; u8 val[SI4713_GET_PROP_NRESP]; /* * .First byte = 0 * .Second byte = property's MSB * .Third byte = property's LSB */ const u8 args[SI4713_GET_PROP_NARGS] = { 0x00, msb(prop), lsb(prop), }; err = si4713_send_command(sdev, SI4713_CMD_GET_PROPERTY, args, ARRAY_SIZE(args), val, ARRAY_SIZE(val), DEFAULT_TIMEOUT); if (err < 0) return err; *pv = compose_u16(val[2], val[3]); v4l2_dbg(1, debug, &sdev->sd, "%s: property=0x%02x value=0x%02x status=0x%02x\n", __func__, prop, *pv, val[0]); return err; }
bool Analyzer::Update(float frequency) { float *fftmem = (float*)(SDRAM_BASE_ADDR + 15*1048576); float *resignal = &fftmem[0*MAXFFTSIZE]; float *imsignal = &fftmem[1*MAXFFTSIZE]; float *refiltered = &fftmem[2*MAXFFTSIZE]; float *imfiltered = &fftmem[3*MAXFFTSIZE]; int extralen = max(int(4 * audio.SampleRateFloat() / frequency), 200); int datalen = (inputRing.used() >> 1); int mindatalen = min(max(int(11 * audio.SampleRateFloat() / frequency), 1024), MAXFFTSIZE); if (!resultready) { if (datalen < mindatalen + extralen) { enoughdata = false; } else { enoughdata = true; fftsizelog2 = msb(datalen); if (fftsizelog2 > MAXFFTSIZELOG2) { fftsizelog2 = MAXFFTSIZELOG2; } fftsize = 1 << fftsizelog2; SplitInput(resignal, refiltered, signalmean, filteredmean, fftsize); } } return !resultready; }
uint32_t get_highest_priority(void) { uint32_t prio = msb(readyqueues[CORE_ID].prio_bitmap); if (prio > MAX_PRIO) return 0; return prio; }
/* otherwise return FALSE */ BOOL MyAppWindow :: QueryForClose( void ) { if(saved == FALSE) //text changed { XMessageBox msb( "Text changed - discard?", "Close Window", MB_YESNO|MB_WARNING|MB_MOVEABLE); if( msb.GetCommand() == MBID_NO) return FALSE; //donït close the window } return TRUE; }
inline unsigned current_precision_of_last_chance_imp(const boost::multiprecision::number<B, ET>& val, const mpl::true_&) { // // We have an arbitrary precision integer, take it's "precision" as the // location of the most-significant-bit less the location of the // least-significant-bit, ie the number of bits required to represent the // the value assuming we will have an exponent to shift things by: // return val.is_zero() ? 1 : digits2_2_10(msb(abs(val)) - lsb(abs(val)) + 1); }
/* * si4713_write_property - modifies a si4713 property * @sdev: si4713_device structure for the device we are communicating * @prop: property identification number * @val: new value for that property */ static int si4713_write_property(struct si4713_device *sdev, u16 prop, u16 val) { int rval; u8 resp[SI4713_SET_PROP_NRESP]; /* * .First byte = 0 * .Second byte = property's MSB * .Third byte = property's LSB * .Fourth byte = value's MSB * .Fifth byte = value's LSB */ const u8 args[SI4713_SET_PROP_NARGS] = { 0x00, msb(prop), lsb(prop), msb(val), lsb(val), }; rval = si4713_send_command(sdev, SI4713_CMD_SET_PROPERTY, args, ARRAY_SIZE(args), resp, ARRAY_SIZE(resp), DEFAULT_TIMEOUT); if (rval < 0) return rval; v4l2_dbg(1, debug, &sdev->sd, "%s: property=0x%02x value=0x%02x status=0x%02x\n", __func__, prop, val, resp[0]); /* * As there is no command response for SET_PROPERTY, * wait Tcomp time to finish before proceed, in order * to have property properly set. */ msleep(TIMEOUT_SET_PROPERTY); return rval; }
void TranspositionTable::set_size(size_t mbSize) { assert(msb((mbSize << 20) / sizeof(TTEntry)) < 32); uint32_t size = ClusterSize << msb((mbSize << 20) / sizeof(TTEntry[ClusterSize])); if (hashMask == size - ClusterSize) return; hashMask = size - ClusterSize; free(mem); mem = calloc(size * sizeof(TTEntry) + CACHE_LINE_SIZE - 1, 1); if (!mem) { std::cerr << "Failed to allocate " << mbSize << "MB for transposition table." << std::endl; exit(EXIT_FAILURE); } table = (TTEntry*)((uintptr_t(mem) + CACHE_LINE_SIZE - 1) & ~(CACHE_LINE_SIZE - 1)); }
static ucs_t convert_to_ucs(struct iconv_ces *ces, const unsigned char **inbuf, apr_size_t *inbytesleft) { ucs_t res; int *state = (int*)ces->data; int mark; if (*inbytesleft < 4) return UCS_CHAR_NONE; /* Not enough bytes in the input buffer */ res = msb(*inbuf); switch (res) { case UCS_CHAR_ZERO_WIDTH_NBSP: *state = 1; mark = 1; break; case UCS_CHAR_INVALID: *state = 2; mark = 1; break; default: mark = 0; } if (mark) { if (*inbytesleft < 8) return UCS_CHAR_NONE; /* Not enough bytes in the input buffer */ *inbytesleft -= 4; res = msb(*inbuf += 4); } if (*state == 2) { res = (unsigned char)(*(*inbuf) ++); res |= (unsigned char)(*(*inbuf) ++) << 8; res |= (unsigned char)(*(*inbuf) ++) << 16; res |= (unsigned char)(*(*inbuf) ++) << 24; } else *inbuf += 4; *inbytesleft -= 4; return res; }
uint16_t SNMPClass::writeHeaders(SNMP_PDU *pdu) { byte i; // SNMP community string if(_dstType == SNMP_PDU_SET){ for(i = _setSize-1; i >= 0 && i <= 30; i--){ _packet[_packetPos--] = (byte)_setCommName[i]; } _packet[_packetPos--] = (byte)_setSize; // length }else if(_dstType == SNMP_PDU_TRAP || _dstType == SNMP_PDU_TRAP2 || _dstType == SNMP_PDU_INFORM_REQUEST){ for(i = _trapSize-1; i >= 0 && i <= 30; i--){ _packet[_packetPos--] = (byte)_trapCommName[i]; } _packet[_packetPos--] = (byte)_trapSize; // length }else { for(i = _getSize-1; i >= 0 && i <= 30; i--){ _packet[_packetPos--] = (byte)_getCommName[i]; } _packet[_packetPos--] = (byte)_getSize; // length } _packet[_packetPos--] = (byte)SNMP_SYNTAX_OCTETS;// type // version _packet[_packetPos--] = (byte)pdu->version;// value _packet[_packetPos--] = 0x01; // length _packet[_packetPos--] = (byte)SNMP_SYNTAX_INT;//type //start of header //length of all data after this point _packet[_packetPos] = lsb(packet_length()+_extra_data_size); _packet[_packetPos-1] = msb(packet_length()+_extra_data_size); _packetPos -= 2; _packet[_packetPos--] = 0x82;//Sending length in two octets _packet[_packetPos--] = (byte)SNMP_SYNTAX_SEQUENCE; //packet type if ( _dstType == SNMP_PDU_SET ) { _packetSize += _setSize; } else if ( _dstType == SNMP_PDU_TRAP ) { _packetSize += _trapSize; } else { _packetSize += _getSize; } return _packetPos; }
static void modmult(Bignum r1, Bignum r2, Bignum modulus, Bignum result) { Bignum temp = newbn(modulus[0]+1); Bignum tmp2 = newbn(modulus[0]+1); int i; int bit, bits, digit, smallbit; enter((">modmult\n")); debug(r1); debug(r2); debug(modulus); for (i=1; i<=result[0]; i++) result[i] = 0; /* result := 0 */ for (i=1; i<=temp[0]; i++) temp[i] = (i > r2[0] ? 0 : r2[i]); /* temp := r2 */ bits = 1+msb(r1); for (bit = 0; bit < bits; bit++) { digit = 1 + bit / 16; smallbit = bit % 16; debug(temp); if (digit <= r1[0] && (r1[digit] & (1<<smallbit))) { dmsg(("bit %d\n", bit)); add(temp, result, tmp2); if (ge(tmp2, modulus)) sub(tmp2, modulus, result); else add(tmp2, Zero, result); debug(result); } add(temp, temp, tmp2); if (ge(tmp2, modulus)) sub(tmp2, modulus, temp); else add(tmp2, Zero, temp); } freebn(temp); freebn(tmp2); debug(result); leave(("<modmult\n")); }
typename enable_if_c<is_integral<Integer>::value, Integer>::type sqrt(const Integer& x, Integer& r) { // // This is slow bit-by-bit integer square root, see for example // http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29 // There are better methods such as http://hal.inria.fr/docs/00/07/28/54/PDF/RR-3805.pdf // and http://hal.inria.fr/docs/00/07/21/13/PDF/RR-4475.pdf which should be implemented // at some point. // Integer s = 0; if(x == 0) { r = 0; return s; } int g = msb(x); if(g == 0) { r = 1; return s; } Integer t = 0; r = x; g /= 2; bit_set(s, g); bit_set(t, 2 * g); r = x - t; --g; do { t = s; t <<= g + 1; bit_set(t, 2 * g); if(t <= r) { bit_set(s, g); r -= t; } --g; } while(g >= 0); return s; }
void ModbusRtu::send(QByteArray &data) { Q_ASSERT(mState == Idle); quint16 crc = Crc16::getValue(data); data.append(static_cast<char>(msb(crc))); data.append(static_cast<char>(lsb(crc))); // Modbus requires a pause between sending of 3.5 times the interval needed // to send a character. We use 4 characters here, just in case... // We also assume 10 bits per caracter (8 data bits, 1 stop bit and 1 parity // bit). Keep in mind that overestimating the character time does not hurt // (a lot), but underestimating does. // Then number of bits devided by the the baudrate (unit: bits/second) gives // us the time in seconds. usleep wants time in microseconds, so we have to // multiply by 1 million. usleep((4 * 10 * 1000 * 1000) / mSerialPort.baudrate); veSerialPutBuf(&mSerialPort, reinterpret_cast<un8 *>(data.data()), static_cast<un32>(data.size())); mTimer->start(); mState = Address; mCurrentSlave = static_cast<quint8>(data[0]); }
//------------------------------------------------ // Insert a time interval data point. The interval // is time elapsed since start_ns, converted to // milliseconds or microseconds as appropriate. // Assumes start_ns was obtained via cf_getns() // some time ago. Generates a histogram with // either: // // bucket millisecond range // ------ ----------------- // 0 0 to 1 (more exactly, 0.999999) // 1 1 to 2 (more exactly, 1.999999) // 2 2 to 4 (more exactly, 3.999999) // 3 4 to 8 (more exactly, 7.999999) // 4 8 to 16 (more exactly, 15.999999) // etc. // // or: // // bucket microsecond range // ------ ----------------- // 0 0 to 1 (more exactly, 0.999) // 1 1 to 2 (more exactly, 1.999) // 2 2 to 4 (more exactly, 3.999) // 3 4 to 8 (more exactly, 7.999) // 4 8 to 16 (more exactly, 15.999) // etc. // void histogram_insert_data_point(histogram *h, uint64_t start_ns) { uint64_t end_ns = cf_getns(); uint64_t delta_t = (end_ns - start_ns) / h->time_div; int bucket = 0; if (delta_t != 0) { bucket = msb(delta_t); if (start_ns > end_ns) { // Either the clock went backwards, or wrapped. (Assume the former, // since it takes ~580 years from 0 to wrap.) cf_warning(AS_INFO, "clock went backwards: start %lu end %lu", start_ns, end_ns); bucket = 0; } } cf_atomic64_incr(&h->counts[bucket]); }
void TranspositionTable::resize(size_t mbSize) { size_t newClusterCount = size_t(1) << msb((mbSize * 1024 * 1024) / sizeof(Cluster)); if (newClusterCount == clusterCount) return; clusterCount = newClusterCount; if (table) { ALIGNED_FREE(table); table = nullptr; } table = (Cluster*)ALIGNED_ALLOC( sizeof(Cluster), clusterCount * sizeof(Cluster)); if (!table) { SYNCCOUT << "info string Failed to allocate " << mbSize << "MB for transposition table." << SYNCENDL; exit(EXIT_FAILURE); } }
/* * si4713_tx_tune_measure - Enters receive mode and measures the received noise * level in units of dBuV on the selected frequency. * The Frequency must be between 76 and 108 MHz in 10 kHz * units and steps of 50 kHz. The command also sets the * antenna tuning capacitance. A value of 0 means * autotuning, and a value of 1 to 191 indicates manual * override. * @sdev: si4713_device structure for the device we are communicating * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz) * @antcap: value of antenna tuning capacitor (0 - 191) */ static int si4713_tx_tune_measure(struct si4713_device *sdev, u16 frequency, u8 antcap) { int err; u8 val[SI4713_TXMEA_NRESP]; /* * .First byte = 0 * .Second byte = frequency's MSB * .Third byte = frequency's LSB * .Fourth byte = antcap */ const u8 args[SI4713_TXMEA_NARGS] = { 0x00, msb(frequency), lsb(frequency), antcap, }; sdev->tune_rnl = DEFAULT_TUNE_RNL; if (antcap > SI4713_MAX_ANTCAP) return -EDOM; err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_MEASURE, args, ARRAY_SIZE(args), val, ARRAY_SIZE(val), DEFAULT_TIMEOUT); if (err < 0) return err; v4l2_dbg(1, debug, &sdev->sd, "%s: frequency=0x%02x antcap=0x%02x status=0x%02x\n", __func__, frequency, antcap, val[0]); return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE); }
int main() { int a,b; scanf("%d %d",&a,&b); printf("%d\n",(1<<msb(a^b))-1); return 0; }
/* Under the 16-byte (128-bit) key at k and the 12-byte (96-bit) nonce at n, encrypt the plaintext at p and store it at c. The length of the plaintext is a multiple of 16 bytes given at len (e.g., len = 2 for a 32-byte p). The length of the ciphertext c is (len+1)*16 bytes. */ void aes128ocb(unsigned char *c, const unsigned char *k, const unsigned char *n, const unsigned char *p, const unsigned int len) { /* Array of zeros for use with aes128e */ unsigned char zeros[16]; int i; for (i = 0; i < 16; ++i) { zeros[i] = 0x00; } unsigned char l[16]; unsigned char l_dollar[16]; aes128e(l, zeros, k); /* Now l is l_star */ doubleB(l, 16); /* Now l is l_dollar */ /* We keep l_dollar for using it for calculate the tag */ for (i = 0; i < 16; ++i) { l_dollar[i] = l[i]; } doubleB(l, 16); /* Now l is l_0 */ /* m = bitlen(P)/128 */ unsigned int m = ((16*len)*8)/128; /* numL is the maximum value of trailing zeros for the given size m */ unsigned int numL = msb(m) + 1; /* ls is the array of all the l_i arrays */ unsigned char ls[numL][16]; int a; for (a = 0; a < numL; ++a) { for (i = 0; i < 16; ++i) { ls[a][i] = l[i]; } doubleB(l, 16); } /* Addition of 0x00000001 to the nonce */ unsigned char nonce[20]; nonce[0] = nonce[1] = nonce[2] = 0x00; nonce[3] = 0x01; a = 0; for (i = 4; i < 20; ++i) { nonce[i] = n[a]; ++a; } /* Bottom is the integer value of the last 6 bits of nonce */ unsigned int bottom = nonce[15]&0x3F; /* Temporal array for aes128e with last 6 bits of nonce to zero */ unsigned char top[16]; for (i = 0; i < 16; ++i) { top[i] = nonce[i]; } top[15] = nonce[15]&0xC0; /* Calculation of ktop using the block cipher */ unsigned char ktop[16]; aes128e(ktop, top, k); /* Stretch is ktop concatenated with the xor of the bits 1...64 and 9...72 of ktop */ unsigned char stretch[24]; for (i = 0; i < 16; ++i) { stretch[i] = ktop[i]; } a = 0; for (i = 16; i < 24; ++i) { stretch[i] = (ktop[a] ^ ktop[a + 1]); ++a; } /* Array of the m offset arrays */ unsigned char offset[m][16]; /* Array of the m checksum arrays */ unsigned char checksum[m][16]; /* Temporal array for get stretch[1 + bottom...128 + bottom] */ unsigned char tempS[24]; for (i = 0; i < 24; ++i) { tempS[i] = stretch[i]; } /* Shifting of stretch bottom times to the left */ for (i = 0; i < bottom; ++i) { shiftB(tempS, 24); } /* Copy of temp array to offset and inicialization of checksum */ for (i = 0; i < 16; ++i) { offset[0][i] = tempS[i]; checksum[0][i] = 0x00; } /* Temporal arrays for use them with aes128 as plaintext and ciphertext */ unsigned char temp1[16]; unsigned char temp2[16]; int ntzV; /* Counters */ int countP1 = 0; int countP2 = 0; int countC = 0; /* Loop over the m blocks */ for (i = 1; i <= m; ++i) { /* Number of trailing zeros in i */ ntzV = ntz(i); /* Calculation of the offset_i with xor betwen offset_{i-1} and l_{ntz(i)} */ for (a = 0; a < 16; ++a) { offset[i][a] = offset[i - 1][a] ^ ls[ntzV][a]; } /* Calculation of xor betwen p_i and offset_i for use it in aes128 */ for (a = 0; a < 16; ++a) { temp1[a] = (p[countP1] ^ offset[i][a]); ++countP1; } aes128e(temp2, temp1, k); /* Calculation of c_i with xor betwen offset_i and result of aes128 */ for (a = 0; a < 16; ++a) { c[countC] = offset[i][a] ^ temp2[a]; ++countC; } /* Calculation of checksum_i with the xor betwen checksum_{i-1} and p_i */ for (a = 0; a < 16; ++a) { checksum[i][a] = checksum[i - 1][a] ^ p[countP2]; ++countP2; } } unsigned char tag[16]; unsigned char tempTag[16]; /* Calculation of the xor betwen checksum_m, offset_m and l_dollar for use it in aes128 to calculate the tag */ int w; for (w = 0; w < 16; ++w) { tempTag[w] = ((l_dollar[w] ^ offset[m][w]) ^ checksum[m][w]); } aes128e(tag, tempTag, k); /* Concatenation of the tag at the end of the ciphertext. 16*m is the current lenght of the cipher lenght and 16*m +16 is the total lenght */ int countTag = 0; for (a = 16*m; a < (16*m + 16); ++a) { c[a] = tag[countTag]; ++countTag; } }