Commit dd5f6e06 authored by Gaëtan Cassiers's avatar Gaëtan Cassiers
Browse files

Initial commit with source

parent 9437496a
#include "parameters.h"
#define CRYPTO_KEYBYTES KEYBYTES
#define CRYPTO_NPUBBYTES 16
#define CRYPTO_NSECBYTES 0
#define CRYPTO_ABYTES 16
#define CRYPTO_NOOVERLAP 1
/* MIT License
*
* Copyright (c) 2019 Gaëtan Cassiers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <string.h>
#include <stdint.h>
#ifdef BENCH_IACA
#include "iacaMarks.h"
#else
#define IACA_START
#define IACA_END
#endif
#include "primitives.h"
#define CLYDE_128_NS 6 // Number of steps
#define CLYDE_128_NR 2 * CLYDE_128_NS // Number of rounds
// Round constants for Clyde-128
static const uint32_t clyde128_rc[CLYDE_128_NR][LS_ROWS] = {
{ 1, 0, 0, 0 }, // 0
{ 0, 1, 0, 0 }, // 1
{ 0, 0, 1, 0 }, // 2
{ 0, 0, 0, 1 }, // 3
{ 1, 1, 0, 0 }, // 4
{ 0, 1, 1, 0 }, // 5
{ 0, 0, 1, 1 }, // 6
{ 1, 1, 0, 1 }, // 7
{ 1, 0, 1, 0 }, // 8
{ 0, 1, 0, 1 }, // 9
{ 1, 1, 1, 0 }, // 10
{ 0, 1, 1, 1 } // 11
};
// Apply a S-box layer to a Clyde-128 state.
static void sbox_layer(uint32_t* state) {
uint32_t y1 = (state[0] & state[1]) ^ state[2];
uint32_t y0 = (state[3] & state[0]) ^ state[1];
uint32_t y3 = (y1 & state[3]) ^ state[0];
uint32_t y2 = (y0 & y1) ^ state[3];
state[0] = y0;
state[1] = y1;
state[2] = y2;
state[3] = y3;
}
// Apply a L-box to a pair of Clyde-128 rows.
#define ROT32(x,n) ((uint32_t)(((x)>>(n))|((x)<<(32-(n)))))
static void lbox(uint32_t* x, uint32_t* y) {
uint32_t a, b, c, d;
a = *x ^ ROT32(*x, 12);
b = *y ^ ROT32(*y, 12);
a = a ^ ROT32(a, 3);
b = b ^ ROT32(b, 3);
a = a ^ ROT32(*x, 17);
b = b ^ ROT32(*y, 17);
c = a ^ ROT32(a, 31);
d = b ^ ROT32(b, 31);
a = a ^ ROT32(d, 26);
b = b ^ ROT32(c, 25);
a = a ^ ROT32(c, 15);
b = b ^ ROT32(d, 15);
*x = a;
*y = b;
}
#define XORLS(DEST, OP) do { \
(DEST)[0] ^= (OP)[0]; \
(DEST)[1] ^= (OP)[1]; \
(DEST)[2] ^= (OP)[2]; \
(DEST)[3] ^= (OP)[3]; } while (0)
void clyde128_encrypt(clyde128_state state, const clyde128_state t, const unsigned char* k) {
// Key schedule
clyde128_state k_st;
memcpy(k_st, k, CLYDE128_NBYTES);
clyde128_state tk[3] = {
{ t[0], t[1], t[2], t[3] },
{ t[0] ^ t[2], t[1] ^ t[3], t[0], t[1] },
{ t[2], t[3], t[0] ^ t[2], t[1] ^ t[3] }
};
XORLS(tk[0], k_st);
XORLS(tk[1], k_st);
XORLS(tk[2], k_st);
// Datapath
XORLS(state, tk[0]);
for (unsigned int s = 0; s < CLYDE_128_NS; s++) {
IACA_START
unsigned int r = 2 * s;
sbox_layer(state);
lbox(&state[0], &state[1]);
lbox(&state[2], &state[3]);
XORLS(state, clyde128_rc[r]);
sbox_layer(state);
lbox(&state[0], &state[1]);
lbox(&state[2], &state[3]);
XORLS(state, clyde128_rc[r+1]);
unsigned int off = (s+1) % 3;
XORLS(state, tk[off]);
}
IACA_END
}
/* MIT License
*
* Copyright (c) 2019 Gaëtan Cassiers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <string.h>
#include <stdint.h>
#ifdef BENCH_IACA
#include "iacaMarks.h"
#else
#define IACA_START
#define IACA_END
#endif
#include "primitives.h"
#define CLYDE_128_NS 6 // Number of steps
#define CLYDE_128_NR 2 * CLYDE_128_NS // Number of rounds
// Round constants for Clyde-128
static const uint32_t clyde128_rc[CLYDE_128_NR][LS_ROWS] = {
{ 1, 0, 0, 0 }, // 0
{ 0, 1, 0, 0 }, // 1
{ 0, 0, 1, 0 }, // 2
{ 0, 0, 0, 1 }, // 3
{ 1, 1, 0, 0 }, // 4
{ 0, 1, 1, 0 }, // 5
{ 0, 0, 1, 1 }, // 6
{ 1, 1, 0, 1 }, // 7
{ 1, 0, 1, 0 }, // 8
{ 0, 1, 0, 1 }, // 9
{ 1, 1, 1, 0 }, // 10
{ 0, 1, 1, 1 } // 11
};
// Apply a inverse S-box layer to a Clyde-128 state.
static void sbox_layer_inv(uint32_t* state) {
uint32_t y3 = (state[0] & state[1]) ^ state[2];
uint32_t y0 = (state[1] & y3) ^ state[3];
uint32_t y1 = (y3 & y0) ^ state[0];
uint32_t y2 = (y0 & y1) ^ state[1];
state[0] = y0;
state[1] = y1;
state[2] = y2;
state[3] = y3;
}
// Apply a inverse L-box to a pair of Clyde-128 rows.
#define ROT32(x,n) ((uint32_t)(((x)>>(n))|((x)<<(32-(n)))))
static void lbox_inv(uint32_t* x, uint32_t* y) {
uint32_t a, b, c, d;
a = *x ^ ROT32(*x, 25);
b = *y ^ ROT32(*y, 25);
c = *x ^ ROT32(a, 31);
d = *y ^ ROT32(b, 31);
c = c ^ ROT32(a, 20);
d = d ^ ROT32(b, 20);
a = c ^ ROT32(c, 31);
b = d ^ ROT32(d, 31);
c = c ^ ROT32(b, 26);
d = d ^ ROT32(a, 25);
a = a ^ ROT32(c, 17);
b = b ^ ROT32(d, 17);
a = ROT32(a, 16);
b = ROT32(b, 16);
*x = a;
*y = b;
}
#define XORLS(DEST, OP) do { \
(DEST)[0] ^= (OP)[0]; \
(DEST)[1] ^= (OP)[1]; \
(DEST)[2] ^= (OP)[2]; \
(DEST)[3] ^= (OP)[3]; } while (0)
void clyde128_decrypt(clyde128_state state, const clyde128_state t, const unsigned char* k) {
// Key schedule
clyde128_state k_st;
memcpy(k_st, k, CLYDE128_NBYTES);
clyde128_state tk[3] = {
{ t[0], t[1], t[2], t[3] },
{ t[0] ^ t[2], t[1] ^ t[3], t[0], t[1] },
{ t[2], t[3], t[0] ^ t[2], t[1] ^ t[3] }
};
XORLS(tk[0], k);
XORLS(tk[1], k);
XORLS(tk[2], k);
// Datapath
for (unsigned int s = 0; s < CLYDE_128_NS; s++) {
IACA_START
unsigned int r = 2 * s;
unsigned int off = (s+1) % 3;
XORLS(state, tk[off]);
XORLS(state, clyde128_rc[r+1]);
lbox_inv(&state[0], &state[1]);
lbox_inv(&state[2], &state[3]);
sbox_layer_inv(state);
XORLS(state, clyde128_rc[r]);
lbox_inv(&state[0], &state[1]);
lbox_inv(&state[2], &state[3]);
sbox_layer_inv(state);
}
IACA_END
XORLS(state, tk[0]);
}
/* MIT License
*
* Copyright (c) 2019 Gaëtan Cassiers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <string.h>
#include <stdint.h>
#ifdef BENCH_IACA
#include "iacaMarks.h"
#else
#define IACA_START
#define IACA_END
#endif
#include "primitives.h"
#define CLYDE_128_NS 6 // Number of steps
#define CLYDE_128_NR 2 * CLYDE_128_NS // Number of rounds
static const uint64_t clyde128_rc_mbx[CLYDE_128_NR][2] = {
{ 2, 0 }, // 0
{ 1, 0 }, // 1
{ 0, 2 }, // 2
{ 0, 1 }, // 3
{ 3, 0 }, // 4
{ 1, 2 }, // 5
{ 0, 3 }, // 6
{ 3, 1 }, // 7
{ 2, 2 }, // 8
{ 1, 1 }, // 9
{ 3, 2 }, // 10
{ 1, 3 } // 11
};
#include <immintrin.h>
#define ROT64(x,n) ((uint64_t)(((x)>>(n))|((x)<<(64-(n)))))
static uint64_t lbox_enc(uint64_t c) {
uint64_t a, b;
a = c ^ ROT64(c,24); // 0x0000000001000001
a ^= ROT64(a, 6); // 0x0000000041000041
a ^= ROT64(c,34); // 0x0000000441000041
b = a ^ ROT64(a,62); // 0x4000000551400051
a ^= ROT64(b,51); // 0x028a0004412a8a41
a ^= ROT64(b,30); // 0x56da0010112a8a40
return a;
}
static void sbox_enc(uint64_t *a, uint64_t *b) {
uint64_t s0 = (*a >> 1) & 0x5555555555555555LL;
uint64_t s1 = (*a) & 0x5555555555555555LL;
uint64_t s2 = (*b >> 1) & 0x5555555555555555LL;
uint64_t s3 = (*b) & 0x5555555555555555LL;
uint64_t y1 = (s0 & s1) ^ s2;
uint64_t y0 = (s3 & s0) ^ s1;
uint64_t y3 = (y1 & s3) ^ s0;
uint64_t y2 = (y0 & y1) ^ s3;
*a = (y0 << 1) | y1;
*b = (y2 << 1) | y3;
}
#define MXB_ENC(x, y) (_pdep_u64((y), 0x5555555555555555LL) | _pdep_u64((x), 0xaaaaaaaaaaaaaaaaLL))
#define MXB_DECX(a) ((uint32_t) _pext_u64((a), 0xaaaaaaaaaaaaaaaaLL))
#define MXB_DECY(a) ((uint32_t) _pext_u64((a), 0x5555555555555555LL))
void clyde128_encrypt(clyde128_state state, const clyde128_state t, const unsigned char* k) {
// Key schedule
clyde128_state k_st;
memcpy(k_st, k, CLYDE128_NBYTES);
uint64_t t_a = MXB_ENC(t[0], t[1]);
uint64_t t_b = MXB_ENC(t[2], t[3]);
uint64_t k_a = MXB_ENC(k_st[0], k_st[1]);
uint64_t k_b = MXB_ENC(k_st[2], k_st[3]);
uint64_t t_x = t_a ^ t_b;
uint64_t tk[3][2] = {
{ t_a ^ k_a, t_b ^ k_b },
{ t_x ^ k_a, t_a ^ k_b },
{ t_b ^ k_a, t_x ^ k_b }
};
// Datapath
uint64_t s_a = MXB_ENC(state[0], state[1]);
uint64_t s_b = MXB_ENC(state[2], state[3]);
s_a ^= tk[0][0];
s_b ^= tk[0][1];
for (unsigned int s = 0; s < CLYDE_128_NS; s++) {
IACA_START
unsigned int r = 2 * s;
sbox_enc(&s_a, &s_b);
s_a = lbox_enc(s_a);
s_b = lbox_enc(s_b);
s_a ^= clyde128_rc_mbx[r][0];
s_b ^= clyde128_rc_mbx[r][1];
sbox_enc(&s_a, &s_b);
s_a = lbox_enc(s_a);
s_b = lbox_enc(s_b);
s_a ^= clyde128_rc_mbx[r+1][0];
s_b ^= clyde128_rc_mbx[r+1][1];
unsigned int off = (s+1)%3;
s_a ^= tk[off][0];
s_b ^= tk[off][1];
}
IACA_END
state[0] = MXB_DECX(s_a);
state[1] = MXB_DECY(s_a);
state[2] = MXB_DECX(s_b);
state[3] = MXB_DECY(s_b);
}
/* MIT License
*
* Copyright (c) 2019 Gaëtan Cassiers
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <string.h>
#include <stdint.h>
#define BENCH_IACA 0
#if BENCH_IACA
#include "iacaMarks.h"
#else
#define IACA_START
#define IACA_END
#endif
#include "primitives.h"
#define CLYDE_128_NS 6 // Number of steps
#define CLYDE_128_NR 2 * CLYDE_128_NS // Number of rounds
static const uint64_t clyde128_rc_mbx[CLYDE_128_NR][2] = {
{ 2, 0 }, // 0
{ 1, 0 }, // 1
{ 0, 2 }, // 2
{ 0, 1 }, // 3
{ 3, 0 }, // 4
{ 1, 2 }, // 5
{ 0, 3 }, // 6
{ 3, 1 }, // 7
{ 2, 2 }, // 8
{ 1, 1 }, // 9
{ 3, 2 }, // 10
{ 1, 3 } // 11
};
#include <immintrin.h>
#define ROT64(x,n) ((uint64_t)(((x)>>(n))|((x)<<(64-(n)))))
static uint64_t lbox_enc_inv(uint64_t c) {
uint64_t a, b;
a = c ^ ROT64(c,50); // 0x0004000000000001
b = c ^ ROT64(a,62); // 0x4001000000000001
b ^= ROT64(a,40); // 0x4001010004000001
a = b ^ ROT64(b,62); // 0x1001414005000001
b ^= ROT64(a,51); // 0x4009810a0e002801
a ^= ROT64(b,34); // 0x2801e14505260429
return ROT64(a,32);
}
static void sbox_enc_inv(uint64_t *a, uint64_t *b) {
uint64_t s0 = (*a >> 1) & 0x5555555555555555LL;
uint64_t s1 = (*a) & 0x5555555555555555LL;
uint64_t s2 = (*b >> 1) & 0x5555555555555555LL;
uint64_t s3 = (*b) & 0x5555555555555555LL;
uint64_t y3 = (s0 & s1) ^ s2;
uint64_t y0 = (s1 & y3) ^ s3;
uint64_t y1 = (y3 & y0) ^ s0;
uint64_t y2 = (y0 & y1) ^ s1;
*a = (y0 << 1) | y1;
*b = (y2 << 1) | y3;
}
#define MXB_ENC(x, y) (_pdep_u64((y), 0x5555555555555555LL) | _pdep_u64((x), 0xaaaaaaaaaaaaaaaaLL))
#define MXB_DECX(a) ((uint32_t) _pext_u64((a), 0xaaaaaaaaaaaaaaaaLL))
#define MXB_DECY(a) ((uint32_t) _pext_u64((a), 0x5555555555555555LL))
void clyde128_encrypt(clyde128_state state, const clyde128_state t, const unsigned char* k) {
// Key schedule
clyde128_state k_st;
memcpy(k_st, k, CLYDE128_NBYTES);
uint64_t t_a = MXB_ENC(t[0], t[1]);
uint64_t t_b = MXB_ENC(t[2], t[3]);
uint64_t k_a = MXB_ENC(k_st[0], k_st[1]);
uint64_t k_b = MXB_ENC(k_st[2], k_st[3]);
uint64_t t_x = t_a ^ t_b;
uint64_t tk[3][2] = {
{ t_a ^ k_a, t_b ^ k_b },
{ t_x ^ k_a, t_a ^ k_b },
{ t_b ^ k_a, t_x ^ k_b }
};
// Datapath
uint64_t s_a = MXB_ENC(state[0], state[1]);
uint64_t s_b = MXB_ENC(state[2], state[3]);
for (int s = CLYDE_128_NS - 1; s >= 0; s--) {
IACA_START
unsigned int r = 2 * s;
unsigned int off = (s+1)%3;
s_a ^= tk[off][0];
s_b ^= tk[off][1];
s_a ^= clyde128_rc_mbx[r+1][0];
s_b ^= clyde128_rc_mbx[r+1][1];
s_a = lbox_enc_inv(s_a);
s_b = lbox_enc_inv(s_b);
sbox_enc_inv(&s_a, &s_b);
s_a ^= clyde128_rc_mbx[r][0];
s_b ^= clyde128_rc_mbx[r][1];
s_a = lbox_enc_inv(s_a);
s_b = lbox_enc_inv(s_b);
sbox_enc_inv(&s_a, &s_b);
}
IACA_END
s_a ^= tk[0][0];
s_b ^= tk[0][1];
state[0] = MXB_DECX(s_a);
state[1] = MXB_DECY(s_a);
state[2] = MXB_DECX(s_b);
state[3] = MXB_DECY(s_b);
}
int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen,
const unsigned char* m, unsigned long long mlen,
const unsigned char* ad, unsigned long long adlen,
const unsigned char* nsec, const unsigned char* npub,
const unsigned char* k);
int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen,
unsigned char* nsec, const unsigned char* c,
unsigned long long clen, const unsigned char* ad,
unsigned long long adlen, const unsigned char* npub,
const unsigned char* k);
/* Spook Reference Implementation v1
*
* Written in 2019 at UCLouvain (Belgium) by Olivier Bronchain, Gaetan Cassiers
* and Charles Momin.
* To the extent possible under law, the author(s) have dedicated all copyright
* and related and neighboring rights to this software to the public domain
* worldwide. This software is distributed without any warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication along with
* this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "crypto_aead.h"
#include "s1p.h"
#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else
#define UNUSED
#endif
// Spook encryption.
int crypto_aead_encrypt(unsigned char* c, unsigned long long* clen,
const unsigned char* m, unsigned long long mlen,
const unsigned char* ad, unsigned long long adlen,
const unsigned char* nsec UNUSED,
const unsigned char* npub, const unsigned char* k) {
unsigned char p[P_NBYTES];
const unsigned char* k_priv;
init_keys(&k_priv, p, k);
s1p_encrypt(c, clen, ad, adlen, m, mlen, k_priv, p, npub);
return 0;
}
// Spook encryption.
int crypto_aead_decrypt(unsigned char* m, unsigned long long* mlen,
unsigned char* nsec UNUSED, const unsigned char* c,
unsigned long long clen, const unsigned char* ad,
unsigned long long adlen, const unsigned char* npub,
const unsigned char* k) {
unsigned char p[P_NBYTES];
const unsigned char* k_priv;
init_keys(&k_priv, p, k);
return s1p_decrypt(m, mlen, ad, adlen, c, clen, k_priv, p, npub);
}
/*
* Copyright (2008-2009) Intel Corporation All Rights Reserved.
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel Corporation
* or its suppliers or licensors. Title to the Material remains with
* Intel Corporation or its suppliers and licensors. The Material
* contains trade secrets and proprietary and confidential information
* of Intel or its suppliers and licensors. The Material is protected
* by worldwide copyright and trade secret laws and treaty provisions.
* No part of the Material may be used, copied, reproduced, modified,
* published, uploaded, posted, transmitted, distributed, or disclosed
* in any way without Intel(R)s prior express written permission.
*
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you by
* disclosure or delivery of the Materials, either expressly, by implication,
* inducement, estoppel or otherwise. Any license under such intellectual
* property rights must be express and approved by Intel in writing.
*/
#if defined (__GNUC__)
#define IACA_SSC_MARK( MARK_ID ) \
__asm__ __volatile__ ( \
"\n\t movl $"#MARK_ID", %%ebx" \
"\n\t .byte 0x64, 0x67, 0x90" \
: : : "memory" );
#else
#define IACA_SSC_MARK(x) {__asm mov ebx, x\
__asm _emit 0x64 \
__asm _emit 0x67 \
__asm _emit 0x90 }
#endif
#define IACA_START {IACA_SSC_MARK(111)}