コード例 #1
0
ファイル: ccec_cp521.c プロジェクト: randombit/hacrypto
static void ccn_mod_521(cczp_const_t zp, cc_unit *r, const cc_unit *a, CC_UNUSED cc_ws_t ws) {
    cc_assert(cczp_n(zp) == CCN521_N);
    cc_unit t[CCN521_N];
    cc_unit t2[CCN521_N];
    cc_unit *select[2] __attribute__((aligned(16))) ={t,t2};
    cc_unit borrow;

#if CCN_UNIT_SIZE == 1
    ccn_shift_right(CCN521_N - 1, t2, &a[CCN521_N - 1], 1); // r = a521,...,a1041
    t2[CCN521_N - 1] += a[CCN521_N - 1] & CC_UNIT_C(1);
    t2[CCN521_N - 1] += ccn_add(CCN521_N - 1,t2,t2,a);
#else
    ccn_shift_right(CCN521_N, t2, &a[CCN512_N], 9);  // r = a521,...,a1041
    t2[CCN512_N] += a[CCN512_N] & CC_UNIT_C(0x1ff);  // r += (a512,...,a520)*2^512
    t2[CCN512_N] += ccn_add(CCN512_N,t2,t2,a);         // r += a0,...,a511
#endif
    borrow=ccn_sub(CCN521_N, t, t2, cczp_prime(zp));
    ccn_set(CCN521_N,r,select[borrow]);
}
コード例 #2
0
ファイル: cczp_div2.c プロジェクト: randombit/hacrypto
void cczp_div2(cczp_const_short_t  zp, cc_unit *r, const cc_unit *x) {
    if (x[0] & 1) {
        /* x is odd r = (x + p) >> 1 */
        cc_unit carry = ccn_add(cczp_n(zp), r, x, cczp_prime(zp));
        ccn_shift_right(cczp_n(zp), r, r, 1);
        r[cczp_n(zp) - 1] |= carry << (CCN_UNIT_BITS - 1);
    } else {
        /* x is even r = x >> 1 */
        ccn_shift_right(cczp_n(zp), r, x, 1);
    }
}
コード例 #3
0
ファイル: ccec_cp384.c プロジェクト: randombit/hacrypto
static void ccn_mod_384(cczp_const_t zp, cc_unit *r, const cc_unit *a, CC_UNUSED cc_ws_t ws) {
    cc_assert(cczp_n(zp) == CCN384_N);
    cc_unit s1[CCN384_N] = { ccn384_32(  Anil,  Anil,  Anil,  Anil,  Anil, A(23), A(22), A(21),  Anil,  Anil,  Anil,  Anil) };
    //cc_unit s2[CCN384_N] = { ccn384_32( A(23), A(22), A(21), A(20), A(19), A(18), A(17), A(16), A(15), A(14), A(13), A(12)) };
    cc_unit s3[CCN384_N] = { ccn384_32( A(20), A(19), A(18), A(17), A(16), A(15), A(14), A(13), A(12), A(23), A(22), A(21)) };
    cc_unit s4[CCN384_N] = { ccn384_32( A(19), A(18), A(17), A(16), A(15), A(14), A(13), A(12), A(20),  Anil, A(23),  Anil) };
    cc_unit s5[CCN384_N] = { ccn384_32(  Anil,  Anil,  Anil,  Anil, A(23), A(22), A(21), A(20),  Anil,  Anil,  Anil,  Anil) };
    cc_unit s6[CCN384_N] = { ccn384_32(  Anil,  Anil,  Anil,  Anil,  Anil,  Anil, A(23), A(22), A(21),  Anil,  Anil, A(20)) };
    cc_unit d1[CCN384_N] = { ccn384_32( A(22), A(21), A(20), A(19), A(18), A(17), A(16), A(15), A(14), A(13), A(12), A(23)) };
    cc_unit d2[CCN384_N] = { ccn384_32(  Anil,  Anil,  Anil,  Anil,  Anil,  Anil,  Anil, A(23), A(22), A(21), A(20),  Anil) };
    cc_unit d3[CCN384_N] = { ccn384_32(  Anil,  Anil,  Anil,  Anil,  Anil,  Anil,  Anil, A(23), A(23),  Anil,  Anil,  Anil) };
    cc_unit *select[2] __attribute__((aligned(16))) ={s1,s3};

    cc_unit carry,carry_mask;
    ccn_add(ccn_nof(160)+1, d2, d2, d3);  // smaller size and no carry possible
    ccn_add(ccn_nof(224)+1, s1, s1, s1);  // smaller size and no carry possible, alternatively cc_shiftl(s1, 1) but add is currently faster.
    ccn_add(ccn_nof(256)+1, s5, s5, s1);  // smaller size and no carry possible
    ccn_add(ccn_nof(256)+1, s5, s5, s6);  // smaller size and no carry possible

    carry = ccn_add(CCN384_N, r, a, &a[CCN384_N]);
    carry += ccn_add(CCN384_N, r, r, s3);
    carry += ccn_add(CCN384_N, r, r, s4);
    carry += ccn_add(CCN384_N, r, r, s5);
    carry -= ccn_sub(CCN384_N, d1, cczp_prime(zp), d1);
    carry += ccn_add(CCN384_N, r, r, d1);
    carry -= ccn_sub(CCN384_N, s3, r, d2);

    /* Reduce r mod p384 by subtraction of up to four multiples of p384. */
    carry_mask=CC_CARRY_3BITS(carry);
    carry -= (carry_mask & ccn_sub(CCN384_N,select[carry_mask],s3,cczp_prime(zp)));
    carry_mask=CC_CARRY_2BITS(carry);
    carry -= (carry_mask & ccn_sub(CCN384_N,select[carry_mask],s3,cczp_prime(zp)));
    carry_mask=CC_CARRY_2BITS(carry);
    carry -= (carry_mask & ccn_sub(CCN384_N,select[carry_mask],s3,cczp_prime(zp)));
    carry ^= ccn_sub(CCN384_N,s1,s3,cczp_prime(zp));

    ccn_set(CCN384_N,r,select[carry]);

    /* Sanity for debug */
    cc_assert(ccn_cmp(CCN384_N, r, cczp_prime(zp)) < 0);

}
コード例 #4
0
int p12_pbe_gen(CFStringRef passphrase, uint8_t *salt_ptr, size_t salt_length, 
    unsigned iter_count, P12_PBE_ID pbe_id, uint8_t *data, size_t length)
{
    unsigned int hash_blocksize = CC_SHA1_BLOCK_BYTES;
    unsigned int hash_outputsize = CC_SHA1_DIGEST_LENGTH;

    if (!passphrase)
        return -1;

    /* generate diversifier block */
    unsigned char diversifier[hash_blocksize];    
    memset(diversifier, pbe_id, sizeof(diversifier));

    /* convert passphrase to BE UTF16 and append double null */
    CFDataRef passphrase_be_unicode = CFStringCreateExternalRepresentation(kCFAllocatorDefault, passphrase, kCFStringEncodingUTF16BE, '\0');
    if (!passphrase_be_unicode)
        return -1;
    uint8_t null_termination[2] = { 0, 0 };
    CFMutableDataRef passphrase_be_unicode_null_term = CFDataCreateMutableCopy(NULL, 0, passphrase_be_unicode);
    CFRelease(passphrase_be_unicode);
    if (!passphrase_be_unicode_null_term)
        return -1;
    CFDataAppendBytes(passphrase_be_unicode_null_term, null_termination, sizeof(null_termination));

    /* generate passphrase block */
    uint8_t *passphrase_data = NULL;
    size_t passphrase_data_len = 0;
    size_t passphrase_length = CFDataGetLength(passphrase_be_unicode_null_term);
    const unsigned char *passphrase_ptr = CFDataGetBytePtr(passphrase_be_unicode_null_term);
    passphrase_data = concatenate_to_blocksize(passphrase_ptr, passphrase_length, hash_blocksize, &passphrase_data_len);
    CFRelease(passphrase_be_unicode_null_term);
    if (!passphrase_data)
        return -1;

    /* generate salt block */
    uint8_t *salt_data = NULL;
    size_t salt_data_len = 0;
    if (salt_length)
        salt_data = concatenate_to_blocksize(salt_ptr, salt_length, hash_blocksize, &salt_data_len);
    if (!salt_data)
        return -1;
    
    /* generate S||P block */
    size_t I_length = salt_data_len + passphrase_data_len;
    uint8_t *I_data = malloc(I_length);
    if (!I_data)
        return -1;
        
    memcpy(I_data + 0, salt_data, salt_data_len);
    memcpy(I_data + salt_data_len, passphrase_data, passphrase_data_len);
    free(salt_data);
    free(passphrase_data);

    /* round up output buffer to multiple of hash block size and allocate */
    size_t hash_output_blocks = (length + hash_outputsize - 1) / hash_outputsize;
    size_t temp_buf_size = hash_output_blocks * hash_outputsize;
    uint8_t *temp_buf = malloc(temp_buf_size);
    uint8_t *cursor = temp_buf;
    if (!temp_buf)
        return -1;

    /* 64 bits cast(s): worst case here is we dont hash all the data and incorectly derive the wrong key,
       when the passphrase + salt are over 2^32 bytes long */
    /* loop over output in hash_output_size increments */
    while (cursor < temp_buf + temp_buf_size) {
        CC_SHA1_CTX ctx;
        CC_SHA1_Init(&ctx);
        CC_SHA1_Update(&ctx, diversifier, (CC_LONG)sizeof(diversifier));
        assert(I_length<=UINT32_MAX); /* debug check. Correct as long as CC_LONG is uint32_t */
        CC_SHA1_Update(&ctx, I_data, (CC_LONG)I_length);
        CC_SHA1_Final(cursor, &ctx);

        /* run block through SHA-1 for iteration count */
        unsigned int i;
        for (i = 1; /*first round done above*/ i < iter_count; i++)
            CC_SHA1(cursor, hash_outputsize, cursor);

        /*
         * b) Concatenate copies of A[i] to create a string B of 
         *    length v bits (the final copy of A[i]i may be truncated 
         *    to create B).
         */
        size_t A_i_len = 0;
        uint8_t *A_i = concatenate_to_blocksize(cursor, 
            hash_outputsize, hash_blocksize, &A_i_len);
        if (!A_i)
            return -1;
        
        /*
         * c) Treating I as a concatenation I[0], I[1], ..., 
         *    I[k-1] of v-bit blocks, where k = ceil(s/v) + ceil(p/v),
         *    modify I by setting I[j]=(I[j]+B+1) mod (2 ** v)
         *    for each j.
         */

        /* tmp1 = B+1 */

        const cc_size tmp_n = ccn_nof_size(A_i_len + 1) > ccn_nof_size(hash_blocksize) ? ccn_nof_size(A_i_len + 1) : ccn_nof_size(hash_blocksize);
        cc_unit tmp1[tmp_n];
        ccn_read_uint(tmp_n, tmp1, A_i_len, A_i);
        ccn_add1(tmp_n, tmp1, tmp1, 1);

        free(A_i);

        cc_unit tmp2[tmp_n];
        unsigned int j;
        for (j = 0; j < I_length; j+=hash_blocksize) {
            /* tempg = I[j];  */
            ccn_read_uint(tmp_n, tmp2, hash_blocksize, I_data + j);
            /* tempg += tmp1 */
            ccn_add(tmp_n, tmp2, tmp2, tmp1);
            
            /* I[j] = tempg mod 2**v
               Just clear all the high bits above 2**v
               In practice at most it rolled over by 1 bit, since all we did was add so
               we should only clear one bit at most.
             */
            size_t bitSize;
            const size_t hash_blocksize_bits = hash_blocksize * 8;
            while ((bitSize = ccn_bitlen(tmp_n, tmp2)) > hash_blocksize_bits)
            {
                ccn_set_bit(tmp2, bitSize - 1, 0);
            }

            ccn_write_uint_padded(tmp_n, tmp2, hash_blocksize, I_data + j);
        }

        cursor += hash_outputsize;
    }

    /*
     * 7. Concatenate A[1], A[2], ..., A[c] together to form a 
     *    pseudo-random bit string, A.
     *
     * 8. Use the first n bits of A as the output of this entire 
     *    process.
     */
    memmove(data, temp_buf, length);
    free(temp_buf);
    free(I_data);
    return 0;
}