Bug#703790: segfaults when building curve25519-donna-c64.c on i386

Peter Palfrader weasel at debian.org
Sat Mar 23 18:40:11 UTC 2013


Package: clang
Version: 1:3.0-6.1
Severity: normal

Trying to build curve25519-donna-c64.c[0] on i386 makes clang segfault.
It builds fine on amd64.

} weasel at dixie:~/tmp$ schroot -r -c $chroot -- clang -v -c curve25519-donna-c64.c
} Debian clang version 3.0-6.1 (tags/RELEASE_30/final) (based on LLVM 3.0)
} Target: i386-pc-linux-gnu
} Thread model: posix
}  "/usr/bin/clang" -cc1 -triple i386-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name curve25519-donna-c64.c -mrelocation-model static -mdisable-fp-elim -masm-verbose -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.22 -momit-leaf-frame-pointer -v -coverage-file curve25519-donna-c64.o -resource-dir /usr/bin/../lib/clang/3.0 -fmodule-cache-path /var/tmp/clang-module-cache -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.0/include -internal-externc-isystem /usr/include/i486-linux-gnu -internal-externc-isystem /usr/include -ferror-limit 19 -fmessage-length 211 -fgnu-runtime -fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-fragile-abi -fdiagnostics-show-option -fcolor-diagnostics -o curve25519-donna-c64.o -x c curve25519-donna-c64.c
} clang -cc1 version 3.0 based upon llvm 3.0 hosted on i386-pc-linux-gnu
} ignoring nonexistent directory "/usr/bin/../lib/clang/3.0/include"
} ignoring nonexistent directory "/usr/include/i486-linux-gnu"
} ignoring nonexistent directory "/usr/include/i486-linux-gnu/"
} ignoring nonexistent directory "/usr/bin/../lib/clang/3.0/include"
} ignoring nonexistent directory "/usr/include/i486-linux-gnu"
} ignoring duplicate directory "/usr/local/include"
} ignoring duplicate directory "/usr/include"
} #include "..." search starts here:
} #include <...> search starts here:
}  /usr/local/include
}  /usr/include
}  /usr/include/i386-linux-gnu/
}  /usr/include/clang/3.0/include/
}  /usr/lib/gcc/i486-linux-gnu/4.6/include/
}  /usr/lib/gcc/i486-linux-gnu/4.6/include-fixed/
} End of search list.
} 0  libLLVM-3.0.so.1 0xf7078fc8
} 1  libLLVM-3.0.so.1 0xf70794e4
} 2                   0xf771e400 __kernel_sigreturn + 0
} 3  libLLVM-3.0.so.1 0xf6fa9451 llvm::SelectionDAG::getNode(unsigned int, llvm::DebugLoc, llvm::EVT, llvm::SDValue) + 81
} 4  libLLVM-3.0.so.1 0xf6fbd25d
} 5  libLLVM-3.0.so.1 0xf6fbc5ca
} 6  libLLVM-3.0.so.1 0xf6fc473a llvm::TargetLowering::LowerCallTo(llvm::SDValue, llvm::Type*, bool, bool, bool, bool, unsigned int, llvm::CallingConv::ID, bool, bool, llvm::SDValue, std::vector<llvm::TargetLowering::ArgListEntry, std::allocator<llvm::TargetLowering::ArgListEntry> >&, llvm::SelectionDAG&, llvm::DebugLoc) const + 4986
} 7  libLLVM-3.0.so.1 0xf6f559dc
} 8  libLLVM-3.0.so.1 0xf6f41f1d
} 9  libLLVM-3.0.so.1 0xf6f52092
} 10 libLLVM-3.0.so.1 0xf6f5a3b1
} 11 libLLVM-3.0.so.1 0xf6f5b51a llvm::SelectionDAG::LegalizeTypes() + 490
} 12 libLLVM-3.0.so.1 0xf6ffb783 llvm::SelectionDAGISel::CodeGenAndEmitDAG() + 211
} 13 libLLVM-3.0.so.1 0xf6ffcca8 llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator<llvm::Instruction const>, llvm::ilist_iterator<llvm::Instruction const>, bool&) + 168
} 14 libLLVM-3.0.so.1 0xf6ffd3f6 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 1846
} 15 libLLVM-3.0.so.1 0xf6ffeda9 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 409
} 16 libLLVM-3.0.so.1 0xf69d277e llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 126
} 17 libLLVM-3.0.so.1 0xf6b72dcc llvm::FPPassManager::runOnFunction(llvm::Function&) + 652
} 18 libLLVM-3.0.so.1 0xf6b72e2c llvm::FPPassManager::runOnModule(llvm::Module&) + 76
} 19 libLLVM-3.0.so.1 0xf6b729f4 llvm::MPPassManager::runOnModule(llvm::Module&) + 500
} 20 libLLVM-3.0.so.1 0xf6b72ae0 llvm::PassManagerImpl::run(llvm::Module&) + 128
} 21 libLLVM-3.0.so.1 0xf6b72b36 llvm::PassManager::run(llvm::Module&) + 38
} 22 clang            0x0831e725 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::Module*, clang::BackendAction, llvm::raw_ostream*) + 2133
} 23 clang            0x0831c8ab clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) + 267
} 24 clang            0x08443141 clang::ParseAST(clang::Sema&, bool) + 465
} 25 clang            0x08221c17 clang::ASTFrontendAction::ExecuteAction() + 103
} 26 clang            0x0831b772 clang::CodeGenAction::ExecuteAction() + 66
} 27 clang            0x08222200 clang::FrontendAction::Execute() + 240
} 28 clang            0x082094f7 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 327
} 29 clang            0x081f32b0 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1072
} 30 clang            0x081ec5da cc1_main(char const**, char const**, char const*, void*) + 874
} 31 clang            0x081eb4d0 main + 6880
} 32 libc.so.6        0xf6079e16 __libc_start_main + 230
} 33 clang            0x081ec0c9
} Stack dump:
} 0.      Program arguments: /usr/bin/clang -cc1 -triple i386-pc-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name curve25519-donna-c64.c -mrelocation-model static -mdisable-fp-elim -masm-verbose -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.22 -momit-leaf-frame-pointer -v -coverage-file curve25519-donna-c64.o -resource-dir /usr/bin/../lib/clang/3.0 -fmodule-cache-path /var/tmp/clang-module-cache -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.0/include -internal-externc-isystem /usr/include/i486-linux-gnu -internal-externc-isystem /usr/include -ferror-limit 19 -fmessage-length 211 -fgnu-runtime -fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-fragile-abi -fdiagnostics-show-option -fcolor-diagnostics -o curve25519-donna-c64.o -x c curve25519-donna-c64.c 
} 1.      <eof> parser at end of file
} 2.      Code generation
} 3.      Running pass 'Function Pass Manager' on module 'curve25519-donna-c64.c'.
} 4.      Running pass 'X86 DAG->DAG Instruction Selection' on function '@curve25519_donna'
} clang: error: unable to execute command: Segmentation fault
} clang: error: clang frontend command failed due to signal 2 (use -v to see invocation)
} clang: note: diagnostic msg: Please submit a bug report to http://llvm.org/bugs/ and include command line arguments and all diagnostic information.
} clang: note: diagnostic msg: Preprocessed source(s) are located at:
} clang: note: diagnostic msg: /tmp/curve25519-donna-c64-svRExf.i

It probably shouldn't segfault.

0. https://raw.github.com/agl/curve25519-donna/d05f13ac8758ce17fdf20fe9f3d842c91992152e/curve25519-donna-c64.c
   https://github.com/agl/curve25519-donna/blob/d05f13ac8758ce17fdf20fe9f3d842c91992152e/curve25519-donna-c64.c
-------------- next part --------------
A non-text attachment was scrubbed...
Name: curve25519-donna-c64.c
Type: text/x-csrc
Size: 13539 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-llvm-team/attachments/20130323/bf23c617/attachment-0001.c>
-------------- next part --------------
# 1 "curve25519-donna-c64.c"
# 1 "curve25519-donna-c64.c" 1
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 129 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "curve25519-donna-c64.c" 2
# 25 "curve25519-donna-c64.c"
# 1 "/usr/include/string.h" 1 3 4
# 27 "/usr/include/string.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 323 "/usr/include/features.h" 3 4
# 1 "/usr/include/i386-linux-gnu/bits/predefs.h" 1 3 4
# 324 "/usr/include/features.h" 2 3 4
# 356 "/usr/include/features.h" 3 4
# 1 "/usr/include/i386-linux-gnu/sys/cdefs.h" 1 3 4
# 359 "/usr/include/i386-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4
# 360 "/usr/include/i386-linux-gnu/sys/cdefs.h" 2 3 4
# 357 "/usr/include/features.h" 2 3 4
# 388 "/usr/include/features.h" 3 4
# 1 "/usr/include/i386-linux-gnu/gnu/stubs.h" 1 3 4



# 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4
# 5 "/usr/include/i386-linux-gnu/gnu/stubs.h" 2 3 4


# 1 "/usr/include/i386-linux-gnu/gnu/stubs-32.h" 1 3 4
# 8 "/usr/include/i386-linux-gnu/gnu/stubs.h" 2 3 4
# 389 "/usr/include/features.h" 2 3 4
# 28 "/usr/include/string.h" 2 3 4






# 1 "/usr/include/clang/3.0/include/stddef.h" 1 3 4
# 31 "/usr/include/clang/3.0/include/stddef.h" 3 4
typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t;



typedef __typeof__(sizeof(int)) size_t;




typedef int wchar_t;
# 35 "/usr/include/string.h" 2 3 4
# 44 "/usr/include/string.h" 3 4
extern void *memcpy (void *__restrict __dest,
       __const void *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));


extern void *memmove (void *__dest, __const void *__src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));






extern void *memccpy (void *__restrict __dest, __const void *__restrict __src,
        int __c, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));





extern void *memset (void *__s, int __c, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));


extern int memcmp (__const void *__s1, __const void *__s2, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
# 95 "/usr/include/string.h" 3 4
extern void *memchr (__const void *__s, int __c, size_t __n)
      __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
# 128 "/usr/include/string.h" 3 4
extern char *strcpy (char *__restrict __dest, __const char *__restrict __src)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));

extern char *strncpy (char *__restrict __dest,
        __const char *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));


extern char *strcat (char *__restrict __dest, __const char *__restrict __src)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));

extern char *strncat (char *__restrict __dest, __const char *__restrict __src,
        size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));


extern int strcmp (__const char *__s1, __const char *__s2)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));

extern int strncmp (__const char *__s1, __const char *__s2, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));


extern int strcoll (__const char *__s1, __const char *__s2)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));

extern size_t strxfrm (char *__restrict __dest,
         __const char *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2)));







# 1 "/usr/include/xlocale.h" 1 3 4
# 28 "/usr/include/xlocale.h" 3 4
typedef struct __locale_struct
{

  struct __locale_data *__locales[13];


  const unsigned short int *__ctype_b;
  const int *__ctype_tolower;
  const int *__ctype_toupper;


  const char *__names[13];
} *__locale_t;


typedef __locale_t locale_t;
# 163 "/usr/include/string.h" 2 3 4


extern int strcoll_l (__const char *__s1, __const char *__s2, __locale_t __l)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2, 3)));

extern size_t strxfrm_l (char *__dest, __const char *__src, size_t __n,
    __locale_t __l) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2, 4)));





extern char *strdup (__const char *__s)
     __attribute__ ((__nothrow__)) __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1)));






extern char *strndup (__const char *__string, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__malloc__)) __attribute__ ((__nonnull__ (1)));
# 235 "/usr/include/string.h" 3 4
extern char *strchr (__const char *__s, int __c)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
# 262 "/usr/include/string.h" 3 4
extern char *strrchr (__const char *__s, int __c)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
# 284 "/usr/include/string.h" 3 4
extern size_t strcspn (__const char *__s, __const char *__reject)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));


extern size_t strspn (__const char *__s, __const char *__accept)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
# 314 "/usr/include/string.h" 3 4
extern char *strpbrk (__const char *__s, __const char *__accept)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
# 342 "/usr/include/string.h" 3 4
extern char *strstr (__const char *__haystack, __const char *__needle)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));




extern char *strtok (char *__restrict __s, __const char *__restrict __delim)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2)));




extern char *__strtok_r (char *__restrict __s,
    __const char *__restrict __delim,
    char **__restrict __save_ptr)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2, 3)));

extern char *strtok_r (char *__restrict __s, __const char *__restrict __delim,
         char **__restrict __save_ptr)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2, 3)));
# 399 "/usr/include/string.h" 3 4
extern size_t strlen (__const char *__s)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));





extern size_t strnlen (__const char *__string, size_t __maxlen)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));





extern char *strerror (int __errnum) __attribute__ ((__nothrow__));
# 427 "/usr/include/string.h" 3 4
extern int strerror_r (int __errnum, char *__buf, size_t __buflen) __asm__ ("" "__xpg_strerror_r") __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (2)));
# 445 "/usr/include/string.h" 3 4
extern char *strerror_l (int __errnum, __locale_t __l) __attribute__ ((__nothrow__));





extern void __bzero (void *__s, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));



extern void bcopy (__const void *__src, void *__dest, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));


extern void bzero (void *__s, size_t __n) __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1)));


extern int bcmp (__const void *__s1, __const void *__s2, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
# 489 "/usr/include/string.h" 3 4
extern char *index (__const char *__s, int __c)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
# 517 "/usr/include/string.h" 3 4
extern char *rindex (__const char *__s, int __c)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));




extern int ffs (int __i) __attribute__ ((__nothrow__)) __attribute__ ((__const__));
# 536 "/usr/include/string.h" 3 4
extern int strcasecmp (__const char *__s1, __const char *__s2)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));


extern int strncasecmp (__const char *__s1, __const char *__s2, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1, 2)));
# 559 "/usr/include/string.h" 3 4
extern char *strsep (char **__restrict __stringp,
       __const char *__restrict __delim)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));




extern char *strsignal (int __sig) __attribute__ ((__nothrow__));


extern char *__stpcpy (char *__restrict __dest, __const char *__restrict __src)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *stpcpy (char *__restrict __dest, __const char *__restrict __src)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));



extern char *__stpncpy (char *__restrict __dest,
   __const char *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
extern char *stpncpy (char *__restrict __dest,
        __const char *__restrict __src, size_t __n)
     __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
# 26 "curve25519-donna-c64.c" 2
# 1 "/usr/include/stdint.h" 1 3 4
# 27 "/usr/include/stdint.h" 3 4
# 1 "/usr/include/i386-linux-gnu/bits/wchar.h" 1 3 4
# 28 "/usr/include/stdint.h" 2 3 4
# 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4
# 29 "/usr/include/stdint.h" 2 3 4








typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_t;



__extension__
typedef long long int int64_t;




typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;

typedef unsigned int uint32_t;





__extension__
typedef unsigned long long int uint64_t;






typedef signed char int_least8_t;
typedef short int int_least16_t;
typedef int int_least32_t;



__extension__
typedef long long int int_least64_t;



typedef unsigned char uint_least8_t;
typedef unsigned short int uint_least16_t;
typedef unsigned int uint_least32_t;



__extension__
typedef unsigned long long int uint_least64_t;






typedef signed char int_fast8_t;





typedef int int_fast16_t;
typedef int int_fast32_t;
__extension__
typedef long long int int_fast64_t;



typedef unsigned char uint_fast8_t;





typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
__extension__
typedef unsigned long long int uint_fast64_t;
# 126 "/usr/include/stdint.h" 3 4
typedef int intptr_t;


typedef unsigned int uintptr_t;
# 138 "/usr/include/stdint.h" 3 4
__extension__
typedef long long int intmax_t;
__extension__
typedef unsigned long long int uintmax_t;
# 27 "curve25519-donna-c64.c" 2

typedef uint8_t u8;
typedef uint64_t limb;
typedef limb felem[5];


typedef unsigned uint128_t __attribute__((mode(TI)));





static inline void __attribute__((always_inline))
fsum(limb *output, const limb *in) {
  output[0] += in[0];
  output[1] += in[1];
  output[2] += in[2];
  output[3] += in[3];
  output[4] += in[4];
}







static inline void __attribute__((always_inline))
fdifference_backwards(felem out, const felem in) {

  static const limb two54m152 = (((limb)1) << 54) - 152;
  static const limb two54m8 = (((limb)1) << 54) - 8;

  out[0] = in[0] + two54m152 - out[0];
  out[1] = in[1] + two54m8 - out[1];
  out[2] = in[2] + two54m8 - out[2];
  out[3] = in[3] + two54m8 - out[3];
  out[4] = in[4] + two54m8 - out[4];
}


static inline void __attribute__((always_inline))
fscalar_product(felem output, const felem in, const limb scalar) {
  uint128_t a;

  a = ((uint128_t) in[0]) * scalar;
  output[0] = ((limb)a) & 0x7ffffffffffff;

  a = ((uint128_t) in[1]) * scalar + ((limb) (a >> 51));
  output[1] = ((limb)a) & 0x7ffffffffffff;

  a = ((uint128_t) in[2]) * scalar + ((limb) (a >> 51));
  output[2] = ((limb)a) & 0x7ffffffffffff;

  a = ((uint128_t) in[3]) * scalar + ((limb) (a >> 51));
  output[3] = ((limb)a) & 0x7ffffffffffff;

  a = ((uint128_t) in[4]) * scalar + ((limb) (a >> 51));
  output[4] = ((limb)a) & 0x7ffffffffffff;

  output[0] += (a >> 51) * 19;
}
# 98 "curve25519-donna-c64.c"
static inline void __attribute__((always_inline))
fmul(felem output, const felem in2, const felem in) {
  uint128_t t[5];
  limb r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c;

  r0 = in[0];
  r1 = in[1];
  r2 = in[2];
  r3 = in[3];
  r4 = in[4];

  s0 = in2[0];
  s1 = in2[1];
  s2 = in2[2];
  s3 = in2[3];
  s4 = in2[4];

  t[0] = ((uint128_t) r0) * s0;
  t[1] = ((uint128_t) r0) * s1 + ((uint128_t) r1) * s0;
  t[2] = ((uint128_t) r0) * s2 + ((uint128_t) r2) * s0 + ((uint128_t) r1) * s1;
  t[3] = ((uint128_t) r0) * s3 + ((uint128_t) r3) * s0 + ((uint128_t) r1) * s2 + ((uint128_t) r2) * s1;
  t[4] = ((uint128_t) r0) * s4 + ((uint128_t) r4) * s0 + ((uint128_t) r3) * s1 + ((uint128_t) r1) * s3 + ((uint128_t) r2) * s2;

  r4 *= 19;
  r1 *= 19;
  r2 *= 19;
  r3 *= 19;

  t[0] += ((uint128_t) r4) * s1 + ((uint128_t) r1) * s4 + ((uint128_t) r2) * s3 + ((uint128_t) r3) * s2;
  t[1] += ((uint128_t) r4) * s2 + ((uint128_t) r2) * s4 + ((uint128_t) r3) * s3;
  t[2] += ((uint128_t) r4) * s3 + ((uint128_t) r3) * s4;
  t[3] += ((uint128_t) r4) * s4;

                  r0 = (limb)t[0] & 0x7ffffffffffff; c = (limb)(t[0] >> 51);
  t[1] += c; r1 = (limb)t[1] & 0x7ffffffffffff; c = (limb)(t[1] >> 51);
  t[2] += c; r2 = (limb)t[2] & 0x7ffffffffffff; c = (limb)(t[2] >> 51);
  t[3] += c; r3 = (limb)t[3] & 0x7ffffffffffff; c = (limb)(t[3] >> 51);
  t[4] += c; r4 = (limb)t[4] & 0x7ffffffffffff; c = (limb)(t[4] >> 51);
  r0 += c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffff;
  r1 += c; c = r1 >> 51; r1 = r1 & 0x7ffffffffffff;
  r2 += c;

  output[0] = r0;
  output[1] = r1;
  output[2] = r2;
  output[3] = r3;
  output[4] = r4;
}

static inline void __attribute__((always_inline))
fsquare_times(felem output, const felem in, limb count) {
  uint128_t t[5];
  limb r0,r1,r2,r3,r4,c;
  limb d0,d1,d2,d4,d419;

  r0 = in[0];
  r1 = in[1];
  r2 = in[2];
  r3 = in[3];
  r4 = in[4];

  do {
    d0 = r0 * 2;
    d1 = r1 * 2;
    d2 = r2 * 2 * 19;
    d419 = r4 * 19;
    d4 = d419 * 2;

    t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 ));
    t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19));
    t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 ));
    t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 ));
    t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 ));

                    r0 = (limb)t[0] & 0x7ffffffffffff; c = (limb)(t[0] >> 51);
    t[1] += c; r1 = (limb)t[1] & 0x7ffffffffffff; c = (limb)(t[1] >> 51);
    t[2] += c; r2 = (limb)t[2] & 0x7ffffffffffff; c = (limb)(t[2] >> 51);
    t[3] += c; r3 = (limb)t[3] & 0x7ffffffffffff; c = (limb)(t[3] >> 51);
    t[4] += c; r4 = (limb)t[4] & 0x7ffffffffffff; c = (limb)(t[4] >> 51);
    r0 += c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffff;
    r1 += c; c = r1 >> 51; r1 = r1 & 0x7ffffffffffff;
    r2 += c;
  } while(--count);

  output[0] = r0;
  output[1] = r1;
  output[2] = r2;
  output[3] = r3;
  output[4] = r4;
}


static limb
load_limb(const u8 *in) {
  return
    ((limb)in[0]) |
    (((limb)in[1]) << 8) |
    (((limb)in[2]) << 16) |
    (((limb)in[3]) << 24) |
    (((limb)in[4]) << 32) |
    (((limb)in[5]) << 40) |
    (((limb)in[6]) << 48) |
    (((limb)in[7]) << 56);
}

static void
store_limb(u8 *out, limb in) {
  out[0] = in & 0xff;
  out[1] = (in >> 8) & 0xff;
  out[2] = (in >> 16) & 0xff;
  out[3] = (in >> 24) & 0xff;
  out[4] = (in >> 32) & 0xff;
  out[5] = (in >> 40) & 0xff;
  out[6] = (in >> 48) & 0xff;
  out[7] = (in >> 56) & 0xff;
}


static void
fexpand(limb *output, const u8 *in) {
  output[0] = load_limb(in) & 0x7ffffffffffff;
  output[1] = (load_limb(in+6) >> 3) & 0x7ffffffffffff;
  output[2] = (load_limb(in+12) >> 6) & 0x7ffffffffffff;
  output[3] = (load_limb(in+19) >> 1) & 0x7ffffffffffff;
  output[4] = (load_limb(in+24) >> 12) & 0x7ffffffffffff;
}




static void
fcontract(u8 *output, const felem input) {
  uint128_t t[5];

  t[0] = input[0];
  t[1] = input[1];
  t[2] = input[2];
  t[3] = input[3];
  t[4] = input[4];

  t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff;
  t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff;
  t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff;
  t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff;
  t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff;

  t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff;
  t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff;
  t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff;
  t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff;
  t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff;




  t[0] += 19;

  t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff;
  t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff;
  t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff;
  t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff;
  t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff;



  t[0] += 0x8000000000000 - 19;
  t[1] += 0x8000000000000 - 1;
  t[2] += 0x8000000000000 - 1;
  t[3] += 0x8000000000000 - 1;
  t[4] += 0x8000000000000 - 1;



  t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff;
  t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff;
  t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff;
  t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff;
  t[4] &= 0x7ffffffffffff;

  store_limb(output, t[0] | (t[1] << 51));
  store_limb(output+8, (t[1] >> 13) | (t[2] << 38));
  store_limb(output+16, (t[2] >> 26) | (t[3] << 25));
  store_limb(output+24, (t[3] >> 39) | (t[4] << 12));
}
# 292 "curve25519-donna-c64.c"
static void
fmonty(limb *x2, limb *z2,
       limb *x3, limb *z3,
       limb *x, limb *z,
       limb *xprime, limb *zprime,
       const limb *qmqp ) {
  limb origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5],
        zzprime[5], zzzprime[5];

  memcpy(origx, x, 5 * sizeof(limb));
  fsum(x, z);
  fdifference_backwards(z, origx);

  memcpy(origxprime, xprime, sizeof(limb) * 5);
  fsum(xprime, zprime);
  fdifference_backwards(zprime, origxprime);
  fmul(xxprime, xprime, z);
  fmul(zzprime, x, zprime);
  memcpy(origxprime, xxprime, sizeof(limb) * 5);
  fsum(xxprime, zzprime);
  fdifference_backwards(zzprime, origxprime);
  fsquare_times(x3, xxprime, 1);
  fsquare_times(zzzprime, zzprime, 1);
  fmul(z3, zzzprime, qmqp);

  fsquare_times(xx, x, 1);
  fsquare_times(zz, z, 1);
  fmul(x2, xx, zz);
  fdifference_backwards(zz, xx);
  fscalar_product(zzz, zz, 121665);
  fsum(zzz, xx);
  fmul(z2, zz, zzz);
}
# 333 "curve25519-donna-c64.c"
static void
swap_conditional(limb a[5], limb b[5], limb iswap) {
  unsigned i;
  const limb swap = -iswap;

  for (i = 0; i < 5; ++i) {
    const limb x = swap & (a[i] ^ b[i]);
    a[i] ^= x;
    b[i] ^= x;
  }
}







static void
cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
  limb a[5] = {0}, b[5] = {1}, c[5] = {1}, d[5] = {0};
  limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
  limb e[5] = {0}, f[5] = {1}, g[5] = {0}, h[5] = {1};
  limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;

  unsigned i, j;

  memcpy(nqpqx, q, sizeof(limb) * 5);

  for (i = 0; i < 32; ++i) {
    u8 byte = n[31 - i];
    for (j = 0; j < 8; ++j) {
      const limb bit = byte >> 7;

      swap_conditional(nqx, nqpqx, bit);
      swap_conditional(nqz, nqpqz, bit);
      fmonty(nqx2, nqz2,
             nqpqx2, nqpqz2,
             nqx, nqz,
             nqpqx, nqpqz,
             q);
      swap_conditional(nqx2, nqpqx2, bit);
      swap_conditional(nqz2, nqpqz2, bit);

      t = nqx;
      nqx = nqx2;
      nqx2 = t;
      t = nqz;
      nqz = nqz2;
      nqz2 = t;
      t = nqpqx;
      nqpqx = nqpqx2;
      nqpqx2 = t;
      t = nqpqz;
      nqpqz = nqpqz2;
      nqpqz2 = t;

      byte <<= 1;
    }
  }

  memcpy(resultx, nqx, sizeof(limb) * 5);
  memcpy(resultz, nqz, sizeof(limb) * 5);
}





static void
crecip(felem out, const felem z) {
  felem a,t0,b,c;

          fsquare_times(a, z, 1);
          fsquare_times(t0, a, 2);
          fmul(b, t0, z);
           fmul(a, b, a);
           fsquare_times(t0, a, 1);
                       fmul(b, t0, b);
                   fsquare_times(t0, b, 5);
                   fmul(b, t0, b);
                    fsquare_times(t0, b, 10);
                   fmul(c, t0, b);
                    fsquare_times(t0, c, 20);
                   fmul(t0, t0, c);
                    fsquare_times(t0, t0, 10);
                   fmul(b, t0, b);
                     fsquare_times(t0, b, 50);
                    fmul(c, t0, b);
                      fsquare_times(t0, c, 100);
                    fmul(t0, t0, c);
                     fsquare_times(t0, t0, 50);
                    fmul(t0, t0, b);
                    fsquare_times(t0, t0, 5);
                   fmul(out, t0, a);
}

int curve25519_donna(u8 *, const u8 *, const u8 *);

int
curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
  limb bp[5], x[5], z[5], zmone[5];
  uint8_t e[32];
  int i;

  for (i = 0;i < 32;++i) e[i] = secret[i];
  e[0] &= 248;
  e[31] &= 127;
  e[31] |= 64;

  fexpand(bp, basepoint);
  cmult(x, z, e, bp);
  crecip(zmone, z);
  fmul(z, x, zmone);
  fcontract(mypublic, z);
  return 0;
}


More information about the Pkg-llvm-team mailing list